Skip to content

Commit 883b8c4

Browse files
committed
finish keychain saving logic
1 parent 319c2c8 commit 883b8c4

File tree

3 files changed

+74
-23
lines changed

3 files changed

+74
-23
lines changed

swift-sdk/Constants.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,7 @@ enum Const {
6363
static let email = "itbl_email"
6464
static let userId = "itbl_userid"
6565
static let authToken = "itbl_auth_token"
66-
static let lastPushPayload = "itbl_last_push_payload"
67-
static let lastPushPayloadExpiration = "itbl_last_push_payload_expiration"
66+
static let lastPushPayloadAndExpiration = "itbl_last_push_payload_and_expiration"
6867
}
6968
}
7069

swift-sdk/Internal/InternalIterableAPI.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider {
522522
let expiration = Calendar.current.date(byAdding: .hour,
523523
value: Const.UserDefault.payloadExpiration,
524524
to: dateProvider.currentDate)
525-
localStorage.save(payload: payload, withExpiration: expiration)
525+
localStorage.saveLastPushPayload(payload, withExpiration: expiration)
526526

527527
if let metadata = IterablePushNotificationMetadata.metadata(fromLaunchOptions: payload) {
528528
if let templateId = metadata.templateId {

swift-sdk/Internal/IterableKeychain.swift

Lines changed: 72 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -64,47 +64,99 @@ class IterableKeychain {
6464
}
6565

6666
func getLastPushPayload(currentDate: Date) -> [AnyHashable: Any]? {
67-
if isLastPushPayloadExpired(currentDate: currentDate) {
68-
wrapper.removeValue(forKey: Const.Keychain.Key.lastPushPayload)
69-
wrapper.removeValue(forKey: Const.Keychain.Key.lastPushPayloadExpiration)
70-
67+
guard let payloadExpirationPair = getPayloadExpirationPairFromKeychain() else {
7168
return nil
7269
}
7370

74-
if let data = wrapper.data(forKey: Const.Keychain.Key.lastPushPayload) {
75-
return (try? JSONSerialization.jsonObject(with: data)) as? [AnyHashable: Any]
71+
if isLastPushPayloadExpired(expiration: payloadExpirationPair.expiration, currentDate: currentDate) {
72+
removePayloadExpirationPairFromKeychain()
73+
return nil
7674
}
7775

78-
return nil
76+
return decodeJsonPayload(payloadExpirationPair.payload)
7977
}
8078

8179
func setLastPushPayload(_ payload: [AnyHashable: Any]?, withExpiration expiration: Date?) {
82-
// save expiration here
83-
84-
guard let value = payload?.jsonValue, JSONSerialization.isValidJSONObject(value) else {
85-
wrapper.removeValue(forKey: Const.Keychain.Key.lastPushPayload)
80+
guard let payload = payload, JSONSerialization.isValidJSONObject(payload) else {
81+
removePayloadExpirationPairFromKeychain()
8682
return
8783
}
8884

89-
do {
90-
let data = try JSONSerialization.data(withJSONObject: value, options: [])
91-
wrapper.set(data, forKey: Const.Keychain.Key.lastPushPayload)
92-
} catch {
93-
wrapper.removeValue(forKey: Const.Keychain.Key.lastPushPayload)
94-
}
85+
savePayloadExpirationPairToKeychain(payload: payload, expiration: expiration)
9586
}
9687

9788
// MARK: - PRIVATE/INTERNAL
9889

9990
private let wrapper: KeychainWrapper
10091

101-
private func isLastPushPayloadExpired(currentDate: Date) -> Bool {
102-
// get expiration here
92+
private func getPayloadExpirationPairFromKeychain() -> (payload: Data, expiration: Date?)? {
93+
// get the value from the keychain
94+
guard let keychainValue = wrapper.data(forKey: Const.Keychain.Key.lastPushPayloadAndExpiration) else {
95+
return nil
96+
}
97+
98+
// decode the payload/expiration pair
99+
guard let payloadExpirationPair = try? JSONDecoder().decode(LastPushPayloadValue.self, from: keychainValue) else {
100+
return nil
101+
}
102+
103+
// cast the payload as a JSON object
104+
guard let lastPushPayloadJSON = try? JSONSerialization.jsonObject(with: payloadExpirationPair.payload, options: []) as? [AnyHashable: Any] else {
105+
return nil
106+
}
107+
108+
return (payload: lastPushPayloadJSON, expiration: payloadExpirationPair.expiration) as? (payload: Data, expiration: Date?)
109+
}
110+
111+
private func savePayloadExpirationPairToKeychain(payload: [AnyHashable: Any]?, expiration: Date?) {
112+
guard let payload = payload else {
113+
removePayloadExpirationPairFromKeychain()
114+
return
115+
}
116+
117+
guard let payloadAsData = encodeJsonPayload(payload) else {
118+
return
119+
}
120+
121+
let payloadExpirationPair = LastPushPayloadValue(payload: payloadAsData, expiration: expiration)
122+
123+
guard let encodedPair = try? JSONEncoder().encode(payloadExpirationPair) else {
124+
return
125+
}
126+
127+
wrapper.set(encodedPair, forKey: Const.Keychain.Key.lastPushPayloadAndExpiration)
128+
}
129+
130+
private func encodeJsonPayload(_ json: [AnyHashable: Any]?) -> Data? {
131+
guard let json = json, JSONSerialization.isValidJSONObject(json) else {
132+
return nil
133+
}
134+
135+
return try? JSONSerialization.data(withJSONObject: json)
136+
}
137+
138+
private func decodeJsonPayload(_ data: Data?) -> [AnyHashable: Any]? {
139+
guard let data = data else {
140+
return nil
141+
}
103142

104-
guard let expiration = wrapper.data(forKey: Const.Keychain.Key.lastPushPayloadExpiration) as? Date else {
143+
return try? JSONSerialization.jsonObject(with: data) as? [AnyHashable: Any]
144+
}
145+
146+
private func removePayloadExpirationPairFromKeychain() {
147+
wrapper.removeValue(forKey: Const.Keychain.Key.lastPushPayloadAndExpiration)
148+
}
149+
150+
private func isLastPushPayloadExpired(expiration: Date?, currentDate: Date) -> Bool {
151+
guard let expiration = expiration else {
105152
return false
106153
}
107154

108155
return !(expiration.timeIntervalSinceReferenceDate > currentDate.timeIntervalSinceReferenceDate)
109156
}
157+
158+
private struct LastPushPayloadValue: Codable {
159+
let payload: Data
160+
let expiration: Date?
161+
}
110162
}

0 commit comments

Comments
 (0)