Skip to content

Commit 084cd0c

Browse files
Merge pull request #444 from Iterable/feature/mob-2529-persist
[MOB-2529] - Persist previous feature state locally.
2 parents ef2c76c + 881589d commit 084cd0c

File tree

8 files changed

+84
-3
lines changed

8 files changed

+84
-3
lines changed

swift-sdk/Constants.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ public enum Const {
5252
static let ddlChecked = "itbl_ddl_checked"
5353
static let deviceId = "itbl_device_id"
5454
static let sdkVersion = "itbl_sdk_version"
55+
static let offlineMode = "itbl_offline_mode"
56+
static let offlineModeBeta = "itbl_offline_mode_beta"
5557

5658
static let payloadExpiration = 24
5759
static let attributionInfoExpiration = 24

swift-sdk/Internal/DependencyContainer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ struct DependencyContainer: DependencyContainerProtocol {
125125
InAppFetcher(apiClient: apiClient)
126126
}
127127

128-
let offlineMode = true
128+
let offlineMode = false
129129
let dateProvider: DateProviderProtocol = SystemDateProvider()
130130
let networkSession: NetworkSessionProtocol = URLSession(configuration: .default)
131131
let notificationStateProvider: NotificationStateProviderProtocol = SystemNotificationStateProvider()

swift-sdk/Internal/IterableAPIInternal.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -663,9 +663,13 @@ final class IterableAPIInternal: NSObject, PushTrackerProtocol, AuthProvider {
663663
private func checkRemoteConfiguration() {
664664
ITBInfo()
665665
requestHandler.getRemoteConfiguration().onSuccess { remoteConfiguration in
666-
self.requestHandler.offlineMode = remoteConfiguration.offlineModeBeta
666+
self.localStorage.offlineMode = remoteConfiguration.offlineMode
667+
self.localStorage.offlineModeBeta = remoteConfiguration.offlineModeBeta
668+
self.requestHandler.offlineMode = remoteConfiguration.isOfflineModeEnabled()
667669
}.onError { error in
668-
ITBError("Could not get remote configuration: \(error.localizedDescription)")
670+
let offlineMode = self.localStorage.isOfflineModeEnabled()
671+
ITBError("Could not get remote configuration: \(error.localizedDescription), defaulting to saved: \(offlineMode)")
672+
self.requestHandler.offlineMode = offlineMode
669673
}
670674
}
671675

swift-sdk/Internal/LocalStorageProtocol.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,18 @@ protocol LocalStorageProtocol {
1111
var ddlChecked: Bool { get set }
1212
var deviceId: String? { get set }
1313
var sdkVersion: String? { get set }
14+
var offlineMode: Bool { get set }
15+
var offlineModeBeta: Bool { get set }
1416
func getAttributionInfo(currentDate: Date) -> IterableAttributionInfo?
1517
func save(attributionInfo: IterableAttributionInfo?, withExpiration expiration: Date?)
1618
func getPayload(currentDate: Date) -> [AnyHashable: Any]?
1719
func save(payload: [AnyHashable: Any]?, withExpiration: Date?)
1820
}
21+
22+
extension LocalStorageProtocol {
23+
24+
func isOfflineModeEnabled() -> Bool {
25+
RemoteConfiguration.isBeta ? offlineModeBeta : offlineMode
26+
}
27+
28+
}

swift-sdk/Internal/Models.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66
import Foundation
77

88
struct RemoteConfiguration: Codable, Equatable {
9+
static let isBeta = true
10+
911
let offlineMode: Bool
1012
let offlineModeBeta: Bool
13+
14+
func isOfflineModeEnabled() -> Bool {
15+
Self.isBeta ? offlineModeBeta : offlineMode
16+
}
17+
1118
}

swift-sdk/Internal/UserDefaultsLocalStorage.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,23 @@ struct UserDefaultsLocalStorage: LocalStorageProtocol {
5757
}
5858
}
5959

60+
var offlineMode: Bool {
61+
get {
62+
return bool(withKey: .offlineMode)
63+
} set {
64+
save(bool: newValue, withKey: .offlineMode)
65+
}
66+
}
67+
68+
var offlineModeBeta: Bool {
69+
get {
70+
return bool(withKey: .offlineModeBeta)
71+
}
72+
set {
73+
save(bool: newValue, withKey: .offlineModeBeta)
74+
}
75+
}
76+
6077
func getAttributionInfo(currentDate: Date) -> IterableAttributionInfo? {
6178
(try? codable(withKey: .attributionInfo, currentDate: currentDate)) ?? nil
6279
}
@@ -185,6 +202,8 @@ struct UserDefaultsLocalStorage: LocalStorageProtocol {
185202
static let ddlChecked = LocalStorageKey(value: Const.UserDefaults.ddlChecked)
186203
static let deviceId = LocalStorageKey(value: Const.UserDefaults.deviceId)
187204
static let sdkVersion = LocalStorageKey(value: Const.UserDefaults.sdkVersion)
205+
static let offlineMode = LocalStorageKey(value: Const.UserDefaults.offlineMode)
206+
static let offlineModeBeta = LocalStorageKey(value: Const.UserDefaults.offlineModeBeta)
188207
}
189208

190209
private struct Envelope: Codable {

tests/common/CommonMocks.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,10 @@ class MockLocalStorage: LocalStorageProtocol {
534534

535535
var sdkVersion: String? = nil
536536

537+
var offlineMode: Bool = false
538+
539+
var offlineModeBeta: Bool = false
540+
537541
func getAttributionInfo(currentDate: Date) -> IterableAttributionInfo? {
538542
guard !MockLocalStorage.isExpired(expiration: attributionInfoExpiration, currentDate: currentDate) else {
539543
return nil

tests/swift-sdk-swift-tests/foundational-tests/LocalStorageTests.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,39 @@ class LocalStorageTests: XCTestCase {
155155
localStorage.authToken = nil
156156
XCTAssertNil(localStorage.authToken)
157157
}
158+
159+
func testOfflineMode() {
160+
let saver = { (storage: LocalStorageProtocol, value: Bool) -> Void in
161+
var localStorage = storage
162+
localStorage.offlineMode = value
163+
}
164+
let retriever = { (storage: LocalStorageProtocol) -> Bool? in
165+
storage.offlineMode
166+
}
167+
168+
testLocalStorage(saver: saver, retriever: retriever, value: true)
169+
testLocalStorage(saver: saver, retriever: retriever, value: false)
170+
}
171+
172+
func testOfflineModeBeta() {
173+
let saver = { (storage: LocalStorageProtocol, value: Bool) -> Void in
174+
var localStorage = storage
175+
localStorage.offlineModeBeta = value
176+
}
177+
let retriever = { (storage: LocalStorageProtocol) -> Bool? in
178+
storage.offlineModeBeta
179+
}
180+
181+
testLocalStorage(saver: saver, retriever: retriever, value: true)
182+
testLocalStorage(saver: saver, retriever: retriever, value: false)
183+
}
184+
185+
private func testLocalStorage<T>(saver: (LocalStorageProtocol, T) -> Void,
186+
retriever: (LocalStorageProtocol) -> T?, value: T) where T: Equatable {
187+
let localStorage = UserDefaultsLocalStorage(userDefaults: LocalStorageTests.getTestUserDefaults())
188+
saver(localStorage, value)
189+
let retrievedLocalStorage = UserDefaultsLocalStorage(userDefaults: LocalStorageTests.getTestUserDefaults())
190+
let retrieved = retriever(retrievedLocalStorage)
191+
XCTAssertEqual(value, retrieved)
192+
}
158193
}

0 commit comments

Comments
 (0)