Skip to content

Commit 557a5ee

Browse files
Merge pull request #445 from Iterable/bug/mob-2543-offline-mode
[MOB-2543] - Fix offline mode issues
2 parents 084cd0c + 821e0ae commit 557a5ee

11 files changed

+99
-98
lines changed

swift-sdk/Internal/DependencyContainer.swift

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,21 @@ protocol DependencyContainerProtocol {
2020

2121
func createInAppFetcher(apiClient: ApiClientProtocol) -> InAppFetcherProtocol
2222
func createPersistenceContextProvider() -> IterablePersistenceContextProvider?
23-
var offlineMode: Bool { get}
2423
func createRequestHandler(apiKey: String,
2524
config: IterableConfig,
2625
endPoint: String,
2726
authProvider: AuthProvider?,
2827
authManager: IterableInternalAuthManagerProtocol,
29-
deviceMetadata: DeviceMetadata) -> RequestHandlerProtocol
28+
deviceMetadata: DeviceMetadata,
29+
offlineMode: Bool) -> RequestHandlerProtocol
3030
}
3131

3232
extension DependencyContainerProtocol {
3333
func createInAppManager(config: IterableConfig,
3434
apiClient: ApiClientProtocol,
35+
requestHandler: RequestHandlerProtocol,
3536
deviceMetadata: DeviceMetadata) -> IterableInternalInAppManagerProtocol {
36-
InAppManager(apiClient: apiClient,
37+
InAppManager(requestHandler: requestHandler,
3738
deviceMetadata: deviceMetadata,
3839
fetcher: createInAppFetcher(apiClient: apiClient),
3940
displayer: inAppDisplayer,
@@ -60,31 +61,30 @@ extension DependencyContainerProtocol {
6061
endPoint: String,
6162
authProvider: AuthProvider?,
6263
authManager: IterableInternalAuthManagerProtocol,
63-
deviceMetadata: DeviceMetadata) -> RequestHandlerProtocol {
64+
deviceMetadata: DeviceMetadata,
65+
offlineMode: Bool) -> RequestHandlerProtocol {
6466
if #available(iOS 10.0, *) {
65-
return RequestHandler(onlineCreator: { [weak authProvider] in
66-
OnlineRequestProcessor(apiKey: apiKey,
67+
let onlineProcessor = OnlineRequestProcessor(apiKey: apiKey,
68+
authProvider: authProvider,
69+
authManager: authManager,
70+
endPoint: endPoint,
71+
networkSession: networkSession,
72+
deviceMetadata: deviceMetadata,
73+
dateProvider: dateProvider)
74+
let offlineProcessor: OfflineRequestProcessor?
75+
if let persistenceContextProvider = createPersistenceContextProvider() {
76+
offlineProcessor = OfflineRequestProcessor(apiKey: apiKey,
6777
authProvider: authProvider,
6878
authManager: authManager,
6979
endPoint: endPoint,
70-
networkSession: networkSession,
7180
deviceMetadata: deviceMetadata,
72-
dateProvider: dateProvider) },
73-
offlineCreator: { [weak authProvider] in
74-
guard let persistenceContextProvider = createPersistenceContextProvider() else {
75-
return nil
76-
}
77-
78-
return OfflineRequestProcessor(apiKey: apiKey,
79-
authProvider: authProvider,
80-
authManager: authManager,
81-
endPoint: endPoint,
82-
deviceMetadata: deviceMetadata,
83-
taskScheduler: createTaskScheduler(persistenceContextProvider: persistenceContextProvider),
84-
taskRunner: createTaskRunner(persistenceContextProvider: persistenceContextProvider),
85-
notificationCenter: notificationCenter)
86-
},
87-
offlineMode: offlineMode)
81+
taskScheduler: createTaskScheduler(persistenceContextProvider: persistenceContextProvider),
82+
taskRunner: createTaskRunner(persistenceContextProvider: persistenceContextProvider),
83+
notificationCenter: notificationCenter)
84+
} else {
85+
offlineProcessor = nil
86+
}
87+
return RequestHandler(onlineProcessor: onlineProcessor, offlineProcessor: offlineProcessor, offlineMode: offlineMode)
8888
} else {
8989
return LegacyRequestHandler(apiKey: apiKey,
9090
authProvider: authProvider,
@@ -125,7 +125,6 @@ struct DependencyContainer: DependencyContainerProtocol {
125125
InAppFetcher(apiClient: apiClient)
126126
}
127127

128-
let offlineMode = false
129128
let dateProvider: DateProviderProtocol = SystemDateProvider()
130129
let networkSession: NetworkSessionProtocol = URLSession(configuration: .default)
131130
let notificationStateProvider: NotificationStateProviderProtocol = SystemNotificationStateProvider()

swift-sdk/Internal/InAppManager.swift

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ protocol IterableInternalInAppManagerProtocol: IterableInAppManagerProtocol, InA
2727
}
2828

2929
class InAppManager: NSObject, IterableInternalInAppManagerProtocol {
30-
init(apiClient: ApiClientProtocol,
30+
init(requestHandler: RequestHandlerProtocol,
3131
deviceMetadata: DeviceMetadata,
3232
fetcher: InAppFetcherProtocol,
3333
displayer: InAppDisplayerProtocol,
@@ -42,7 +42,7 @@ class InAppManager: NSObject, IterableInternalInAppManagerProtocol {
4242
retryInterval: Double) {
4343
ITBInfo()
4444

45-
self.apiClient = apiClient
45+
self.requestHandler = requestHandler
4646
self.deviceMetadata = deviceMetadata
4747
self.fetcher = fetcher
4848
self.displayer = displayer
@@ -233,7 +233,9 @@ class InAppManager: NSObject, IterableInternalInAppManagerProtocol {
233233

234234
// track in-app delivery
235235
mergeMessagesResult.deliveredMessages.forEach {
236-
_ = apiClient?.track(inAppDelivery: InAppMessageContext.from(message: $0, location: nil))
236+
requestHandler?.track(inAppDelivery: $0,
237+
onSuccess: nil,
238+
onFailure: nil)
237239
}
238240

239241
finishSync(inboxChanged: mergeMessagesResult.inboxChanged)
@@ -318,7 +320,9 @@ class InAppManager: NSObject, IterableInternalInAppManagerProtocol {
318320
self.scheduleNextInAppMessage()
319321

320322
if consume {
321-
self.apiClient?.inAppConsume(messageId: message.messageId)
323+
self.requestHandler?.inAppConsume(message.messageId,
324+
onSuccess: nil,
325+
onFailure: nil)
322326
}
323327
}
324328
}
@@ -481,9 +485,11 @@ class InAppManager: NSObject, IterableInternalInAppManagerProtocol {
481485
ITBInfo()
482486

483487
updateMessage(message, didProcessTrigger: true, consumed: true)
484-
let messageContext = InAppMessageContext.from(message: message, location: location, inboxSessionId: inboxSessionId)
485-
apiClient?.inAppConsume(inAppMessageContext: messageContext, source: source)
486-
488+
requestHandler?.inAppConsume(message: message,
489+
location: location,
490+
source: source,
491+
onSuccess: nil,
492+
onFailure: nil)
487493
callbackQueue.async {
488494
self.notificationCenter.post(name: .iterableInboxChanged, object: self, userInfo: nil)
489495
}
@@ -518,7 +524,7 @@ class InAppManager: NSObject, IterableInternalInAppManagerProtocol {
518524
}
519525
}
520526

521-
private weak var apiClient: ApiClientProtocol?
527+
private weak var requestHandler: RequestHandlerProtocol?
522528
private let deviceMetadata: DeviceMetadata
523529
private let fetcher: InAppFetcherProtocol
524530
private let displayer: InAppDisplayerProtocol

swift-sdk/Internal/IterableAPIInternal.swift

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ final class IterableAPIInternal: NSObject, PushTrackerProtocol, AuthProvider {
6363
lazy var inAppManager: IterableInternalInAppManagerProtocol = {
6464
self.dependencyContainer.createInAppManager(config: self.config,
6565
apiClient: self.apiClient,
66+
requestHandler: self.requestHandler,
6667
deviceMetadata: deviceMetadata)
6768
}()
6869

@@ -408,12 +409,14 @@ final class IterableAPIInternal: NSObject, PushTrackerProtocol, AuthProvider {
408409
}()
409410

410411
private lazy var requestHandler: RequestHandlerProtocol = {
411-
dependencyContainer.createRequestHandler(apiKey: apiKey,
412-
config: config,
413-
endPoint: apiEndPoint,
414-
authProvider: self,
415-
authManager: authManager,
416-
deviceMetadata: deviceMetadata)
412+
let offlineMode = self.localStorage.isOfflineModeEnabled()
413+
return dependencyContainer.createRequestHandler(apiKey: apiKey,
414+
config: config,
415+
endPoint: apiEndPoint,
416+
authProvider: self,
417+
authManager: authManager,
418+
deviceMetadata: deviceMetadata,
419+
offlineMode: offlineMode)
417420
}()
418421

419422
private var deviceAttributes = [String: String]()
@@ -666,10 +669,10 @@ final class IterableAPIInternal: NSObject, PushTrackerProtocol, AuthProvider {
666669
self.localStorage.offlineMode = remoteConfiguration.offlineMode
667670
self.localStorage.offlineModeBeta = remoteConfiguration.offlineModeBeta
668671
self.requestHandler.offlineMode = remoteConfiguration.isOfflineModeEnabled()
672+
ITBInfo("setting offlineMode: \(self.requestHandler.offlineMode)")
669673
}.onError { error in
670-
let offlineMode = self.localStorage.isOfflineModeEnabled()
671-
ITBError("Could not get remote configuration: \(error.localizedDescription), defaulting to saved: \(offlineMode)")
672-
self.requestHandler.offlineMode = offlineMode
674+
let offlineMode = self.requestHandler.offlineMode
675+
ITBError("Could not get remote configuration: \(error.localizedDescription), using saved value: \(offlineMode)")
673676
}
674677
}
675678

swift-sdk/Internal/LegacyRequestHandler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import Foundation
66

77
/// Request handling pre iOS 10.0
8-
struct LegacyRequestHandler: RequestHandlerProtocol {
8+
class LegacyRequestHandler: RequestHandlerProtocol {
99
init(apiKey: String,
1010
authProvider: AuthProvider?,
1111
authManager: IterableInternalAuthManagerProtocol?,

swift-sdk/Internal/RequestHandler.swift

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ import Foundation
66

77
@available(iOS 10.0, *)
88
class RequestHandler: RequestHandlerProtocol {
9-
init(onlineCreator: @escaping () -> OnlineRequestProcessor,
10-
offlineCreator: @escaping () -> OfflineRequestProcessor?,
9+
init(onlineProcessor: OnlineRequestProcessor,
10+
offlineProcessor: OfflineRequestProcessor?,
1111
offlineMode: Bool = true) {
1212
ITBInfo()
13-
self.onlineCreator = onlineCreator
14-
self.offlineCreator = offlineCreator
13+
self.onlineProcessor = onlineProcessor
14+
self.offlineProcessor = offlineProcessor
1515
self.offlineMode = offlineMode
1616
}
1717

@@ -251,16 +251,8 @@ class RequestHandler: RequestHandlerProtocol {
251251
}
252252
}
253253

254-
private let onlineCreator: () -> OnlineRequestProcessor
255-
private let offlineCreator: () -> OfflineRequestProcessor?
256-
257-
private lazy var offlineProcessor: OfflineRequestProcessor? = {
258-
offlineCreator()
259-
}()
260-
261-
private lazy var onlineProcessor: OnlineRequestProcessor = {
262-
onlineCreator()
263-
}()
254+
private let offlineProcessor: OfflineRequestProcessor?
255+
private let onlineProcessor: OnlineRequestProcessor
264256

265257
private func chooseRequestProcessor() -> RequestProcessorProtocol {
266258
if offlineMode {

swift-sdk/Internal/RequestHandlerProtocol.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import Foundation
66

77
/// `IterableAPIinternal` will delegate all network related calls to this protocol.
8-
protocol RequestHandlerProtocol {
8+
protocol RequestHandlerProtocol: class {
99
var offlineMode: Bool { get set }
1010

1111
func start()

tests/common/CommonExtensions.swift

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ class MockDependencyContainer: DependencyContainerProtocol {
8080
let applicationStateProvider: ApplicationStateProviderProtocol
8181
let notificationCenter: NotificationCenterProtocol
8282
let apnsTypeChecker: APNSTypeCheckerProtocol
83-
let offlineMode: Bool
8483

8584
init(dateProvider: DateProviderProtocol,
8685
networkSession: NetworkSessionProtocol,
@@ -92,8 +91,7 @@ class MockDependencyContainer: DependencyContainerProtocol {
9291
urlOpener: UrlOpenerProtocol,
9392
applicationStateProvider: ApplicationStateProviderProtocol,
9493
notificationCenter: NotificationCenterProtocol,
95-
apnsTypeChecker: APNSTypeCheckerProtocol,
96-
offlineMode: Bool) {
94+
apnsTypeChecker: APNSTypeCheckerProtocol) {
9795
self.dateProvider = dateProvider
9896
self.networkSession = networkSession
9997
self.notificationStateProvider = notificationStateProvider
@@ -105,7 +103,6 @@ class MockDependencyContainer: DependencyContainerProtocol {
105103
self.applicationStateProvider = applicationStateProvider
106104
self.notificationCenter = notificationCenter
107105
self.apnsTypeChecker = apnsTypeChecker
108-
self.offlineMode = offlineMode
109106
}
110107

111108
func createInAppFetcher(apiClient _: ApiClientProtocol) -> InAppFetcherProtocol {
@@ -130,8 +127,7 @@ extension IterableAPI {
130127
urlOpener: UrlOpenerProtocol = MockUrlOpener(),
131128
applicationStateProvider: ApplicationStateProviderProtocol = UIApplication.shared,
132129
notificationCenter: NotificationCenterProtocol = NotificationCenter.default,
133-
apnsTypeChecker: APNSTypeCheckerProtocol = APNSTypeChecker(),
134-
offlineMode: Bool = false) {
130+
apnsTypeChecker: APNSTypeCheckerProtocol = APNSTypeChecker()) {
135131
let mockDependencyContainer = MockDependencyContainer(dateProvider: dateProvider,
136132
networkSession: networkSession,
137133
notificationStateProvider: notificationStateProvider,
@@ -142,8 +138,7 @@ extension IterableAPI {
142138
urlOpener: urlOpener,
143139
applicationStateProvider: applicationStateProvider,
144140
notificationCenter: notificationCenter,
145-
apnsTypeChecker: apnsTypeChecker,
146-
offlineMode: offlineMode)
141+
apnsTypeChecker: apnsTypeChecker)
147142

148143
internalImplementation = IterableAPIInternal(apiKey: apiKey,
149144
launchOptions: launchOptions,
@@ -173,8 +168,7 @@ extension IterableAPIInternal {
173168
urlOpener: UrlOpenerProtocol = MockUrlOpener(),
174169
applicationStateProvider: ApplicationStateProviderProtocol = UIApplication.shared,
175170
notificationCenter: NotificationCenterProtocol = NotificationCenter.default,
176-
apnsTypeChecker: APNSTypeCheckerProtocol = APNSTypeChecker(),
177-
offlineMode: Bool = false) -> IterableAPIInternal {
171+
apnsTypeChecker: APNSTypeCheckerProtocol = APNSTypeChecker()) -> IterableAPIInternal {
178172
let mockDependencyContainer = MockDependencyContainer(dateProvider: dateProvider,
179173
networkSession: networkSession,
180174
notificationStateProvider: notificationStateProvider,
@@ -185,8 +179,7 @@ extension IterableAPIInternal {
185179
urlOpener: urlOpener,
186180
applicationStateProvider: applicationStateProvider,
187181
notificationCenter: notificationCenter,
188-
apnsTypeChecker: apnsTypeChecker,
189-
offlineMode: offlineMode)
182+
apnsTypeChecker: apnsTypeChecker)
190183

191184
let internalImplementation = IterableAPIInternal(apiKey: apiKey,
192185
launchOptions: launchOptions,

0 commit comments

Comments
 (0)