Skip to content

Commit a871948

Browse files
authored
Merge branch 'master' into MOB-6106-Application-Directory-for-json-file-storage
2 parents 441bdf9 + 33d88c9 commit a871948

10 files changed

+41
-270
lines changed

notification-extension/ITBNotificationServiceExtension.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,37 @@
44

55
import UserNotifications
66

7+
public protocol ITBNotificationServiceExtensionDelegate {
8+
func notificationServiceDidReceive(_ request: UNNotificationRequest, bestAttemptContent: UNMutableNotificationContent, contentHandler: @escaping (UNNotificationContent) -> Void)
9+
}
10+
711
@objc open class ITBNotificationServiceExtension: UNNotificationServiceExtension {
812
var contentHandler: ((UNNotificationContent) -> Void)?
913
var bestAttemptContent: UNMutableNotificationContent?
14+
public static var itblNotificationDelegate: ITBNotificationServiceExtensionDelegate?
1015

1116
@objc override open func didReceive(_ request: UNNotificationRequest,
1217
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
1318
self.contentHandler = contentHandler
1419
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
1520

21+
if let itblNotificationDelegate = ITBNotificationServiceExtension.itblNotificationDelegate,
22+
let bestAttemptContent = bestAttemptContent {
23+
24+
let result = request.content.userInfo.contains {
25+
guard let itbl = $0.key as? String else {
26+
print("Iterable SDK notification service extension: failed to cast JSON key to string")
27+
return false
28+
}
29+
return itbl == JsonKey.Payload.metadata
30+
}
31+
32+
if !result {
33+
itblNotificationDelegate.notificationServiceDidReceive(request, bestAttemptContent: bestAttemptContent, contentHandler: contentHandler)
34+
return
35+
}
36+
}
37+
1638
resolveCategory(from: request.content)
1739

1840
retrieveAttachment(from: request.content)

swift-sdk/Constants.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ enum Const {
4242
}
4343

4444
public enum UserDefault {
45-
static let payloadKey = "itbl_payload_key"
4645
static let attributionInfoKey = "itbl_attribution_info_key"
4746
static let emailKey = "itbl_email"
4847
static let userIdKey = "itbl_userid"
@@ -52,7 +51,6 @@ enum Const {
5251
static let sdkVersion = "itbl_sdk_version"
5352
static let offlineMode = "itbl_offline_mode"
5453

55-
static let payloadExpiration = 24
5654
static let attributionInfoExpiration = 24
5755
}
5856

@@ -63,7 +61,6 @@ enum Const {
6361
static let email = "itbl_email"
6462
static let userId = "itbl_userid"
6563
static let authToken = "itbl_auth_token"
66-
static let lastPushPayloadAndExpiration = "itbl_last_push_payload_and_expiration"
6764
}
6865
}
6966

swift-sdk/Internal/InternalIterableAPI.swift

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,14 @@ import UIKit
77

88
final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider {
99
var apiKey: String
10-
10+
var lastPushPayload: [AnyHashable: Any]? {
11+
get {
12+
_payloadData
13+
} set {
14+
setPayloadData(newValue)
15+
}
16+
}
17+
1118
var email: String? {
1219
get {
1320
_email
@@ -46,10 +53,6 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider {
4653
appPackageName: Bundle.main.appPackageName ?? "")
4754
}
4855

49-
var lastPushPayload: [AnyHashable: Any]? {
50-
localStorage.getLastPushPayload(dateProvider.currentDate)
51-
}
52-
5356
var attributionInfo: IterableAttributionInfo? {
5457
get {
5558
localStorage.getAttributionInfo(currentDate: dateProvider.currentDate)
@@ -85,6 +88,7 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider {
8588
urlDelegate: config.urlDelegate,
8689
urlOpener: urlOpener,
8790
allowedProtocols: config.allowedProtocols)
91+
8892
pending.onSuccess { attributionInfo in
8993
if let attributionInfo = attributionInfo {
9094
self.attributionInfo = attributionInfo
@@ -100,6 +104,11 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider {
100104
func removeDeviceAttribute(name: String) {
101105
deviceAttributes.removeValue(forKey: name)
102106
}
107+
108+
func setPayloadData(_ data: [AnyHashable: Any]?) {
109+
ITBInfo()
110+
_payloadData = data
111+
}
103112

104113
func setEmail(_ email: String?, authToken: String? = nil) {
105114
ITBInfo()
@@ -416,6 +425,7 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider {
416425
private var deepLinkManager: DeepLinkManager
417426

418427
private var _email: String?
428+
private var _payloadData: [AnyHashable: Any]?
419429
private var _userId: String?
420430

421431
/// the hex representation of this device token
@@ -537,15 +547,15 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider {
537547
}
538548

539549
private func save(pushPayload payload: [AnyHashable: Any]) {
540-
let expiration = Calendar.current.date(byAdding: .hour,
541-
value: Const.UserDefault.payloadExpiration,
542-
to: dateProvider.currentDate)
543-
localStorage.saveLastPushPayload(payload, withExpiration: expiration)
544550

545551
if let metadata = IterablePushNotificationMetadata.metadata(fromLaunchOptions: payload) {
546552
if let templateId = metadata.templateId {
547553
attributionInfo = IterableAttributionInfo(campaignId: metadata.campaignId, templateId: templateId, messageId: metadata.messageId)
548554
}
555+
556+
if !metadata.isGhostPush {
557+
lastPushPayload = payload
558+
}
549559
}
550560
}
551561

swift-sdk/Internal/IterableKeychain.swift

Lines changed: 0 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -63,74 +63,10 @@ class IterableKeychain {
6363
}
6464
}
6565

66-
func getLastPushPayload(currentDate: Date) -> [AnyHashable: Any]? {
67-
guard let payloadExpirationPair = getPayloadExpirationPairFromKeychain() else {
68-
return nil
69-
}
70-
71-
if isLastPushPayloadExpired(expiration: payloadExpirationPair.expiration, currentDate: currentDate) {
72-
removePayloadExpirationPairFromKeychain()
73-
return nil
74-
}
75-
76-
return decodeJsonPayload(payloadExpirationPair.payload)
77-
}
78-
79-
func setLastPushPayload(_ payload: [AnyHashable: Any]?, withExpiration expiration: Date?) {
80-
guard let payload = payload, JSONSerialization.isValidJSONObject(payload) else {
81-
removePayloadExpirationPairFromKeychain()
82-
return
83-
}
84-
85-
savePayloadExpirationPairToKeychain(payload: payload, expiration: expiration)
86-
}
87-
8866
// MARK: - PRIVATE/INTERNAL
8967

9068
private let wrapper: KeychainWrapper
9169

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-
guard let lastPushPayloadData = try? JSONSerialization.data(withJSONObject: lastPushPayloadJSON) else {
109-
return nil
110-
}
111-
112-
return (payload: lastPushPayloadData, expiration: payloadExpirationPair.expiration)
113-
}
114-
115-
private func savePayloadExpirationPairToKeychain(payload: [AnyHashable: Any]?, expiration: Date?) {
116-
guard let payload = payload else {
117-
removePayloadExpirationPairFromKeychain()
118-
return
119-
}
120-
121-
guard let payloadAsData = encodeJsonPayload(payload) else {
122-
return
123-
}
124-
125-
let payloadExpirationPair = LastPushPayloadValue(payload: payloadAsData, expiration: expiration)
126-
127-
guard let encodedPair = try? JSONEncoder().encode(payloadExpirationPair) else {
128-
return
129-
}
130-
131-
wrapper.set(encodedPair, forKey: Const.Keychain.Key.lastPushPayloadAndExpiration)
132-
}
133-
13470
private func encodeJsonPayload(_ json: [AnyHashable: Any]?) -> Data? {
13571
guard let json = json, JSONSerialization.isValidJSONObject(json) else {
13672
return nil
@@ -147,20 +83,4 @@ class IterableKeychain {
14783
return try? JSONSerialization.jsonObject(with: data) as? [AnyHashable: Any]
14884
}
14985

150-
private func removePayloadExpirationPairFromKeychain() {
151-
wrapper.removeValue(forKey: Const.Keychain.Key.lastPushPayloadAndExpiration)
152-
}
153-
154-
private func isLastPushPayloadExpired(expiration: Date?, currentDate: Date) -> Bool {
155-
guard let expiration = expiration else {
156-
return false
157-
}
158-
159-
return !(expiration.timeIntervalSinceReferenceDate > currentDate.timeIntervalSinceReferenceDate)
160-
}
161-
162-
private struct LastPushPayloadValue: Codable {
163-
let payload: Data
164-
let expiration: Date?
165-
}
16686
}

swift-sdk/Internal/IterableUserDefaults.swift

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -78,33 +78,9 @@ class IterableUserDefaults {
7878
try? save(codable: attributionInfo, withKey: .attributionInfo, andExpiration: expiration)
7979
}
8080

81-
// migrated to IterableKeychain
82-
func getPayload(currentDate: Date) -> [AnyHashable: Any]? {
83-
(try? dict(withKey: .payload, currentDate: currentDate)) ?? nil
84-
}
85-
86-
// migrated to IterableKeychain
87-
func save(payload: [AnyHashable: Any]?, withExpiration expiration: Date?) {
88-
try? save(dict: payload, withKey: .payload, andExpiration: expiration)
89-
}
9081

9182
// MARK: data migration functions
9283

93-
func getLastPushPayloadExpirationPairForMigration() -> (payload: [AnyHashable: Any]?, expiration: Date?)? {
94-
guard let encodedEnvelope = userDefaults.value(forKey: UserDefaultsKey.payload.value) as? Data else {
95-
return nil
96-
}
97-
98-
do {
99-
let envelope = try JSONDecoder().decode(Envelope.self, from: encodedEnvelope)
100-
let decoded = try JSONSerialization.jsonObject(with: envelope.payload, options: []) as? [AnyHashable: Any]
101-
102-
return (payload: decoded, envelope.expiration)
103-
} catch {
104-
return nil
105-
}
106-
}
107-
10884
func getAuthDataForMigration() -> (email: String?, userId: String?, authToken: String?) {
10985
return (email: email, userId: userId, authToken: authToken)
11086
}
@@ -212,8 +188,6 @@ class IterableUserDefaults {
212188
private init(value: String) {
213189
self.value = value
214190
}
215-
216-
static let payload = UserDefaultsKey(value: Const.UserDefault.payloadKey)
217191
static let attributionInfo = UserDefaultsKey(value: Const.UserDefault.attributionInfoKey)
218192
static let email = UserDefaultsKey(value: Const.UserDefault.emailKey)
219193
static let userId = UserDefaultsKey(value: Const.UserDefault.userIdKey)

swift-sdk/Internal/LocalStorage.swift

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -75,22 +75,11 @@ struct LocalStorage: LocalStorageProtocol {
7575
iterableUserDefaults.save(attributionInfo: attributionInfo, withExpiration: expiration)
7676
}
7777

78-
func getLastPushPayload(_ currentDate: Date) -> [AnyHashable: Any]? {
79-
return keychain.getLastPushPayload(currentDate: currentDate)
80-
}
81-
82-
func saveLastPushPayload(_ payload: [AnyHashable: Any]?, withExpiration expiration: Date?) {
83-
keychain.setLastPushPayload(payload, withExpiration: expiration)
84-
}
85-
8678
func upgrade() {
8779
ITBInfo()
8880

8981
/// moves `email`, `userId`, and `authToken` from `UserDefaults` to `IterableKeychain`
9082
moveAuthDataFromUserDefaultsToKeychain()
91-
92-
/// moves `lastPushPayload` from `UserDefaults` to `IterableKeychain`
93-
moveLastPushPayloadFromUserDefaultsToKeychain()
9483
}
9584

9685
// MARK: Private
@@ -131,13 +120,4 @@ struct LocalStorage: LocalStorageProtocol {
131120
ITBInfo("UPDATED: migrated authToken from UserDefaults to IterableKeychain")
132121
}
133122
}
134-
135-
private func moveLastPushPayloadFromUserDefaultsToKeychain() {
136-
if let (userDefaultLastPushPayload, expiration) = iterableUserDefaults.getLastPushPayloadExpirationPairForMigration() {
137-
keychain.setLastPushPayload(userDefaultLastPushPayload, withExpiration: expiration)
138-
iterableUserDefaults.save(payload: nil, withExpiration: nil)
139-
140-
ITBInfo("UPDATED: migrated lastPushPayload from UserDefaults to IterableKeychain")
141-
}
142-
}
143123
}

swift-sdk/Internal/LocalStorageProtocol.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@ protocol LocalStorageProtocol {
2323

2424
func save(attributionInfo: IterableAttributionInfo?, withExpiration expiration: Date?)
2525

26-
func getLastPushPayload(_ currentDate: Date) -> [AnyHashable: Any]?
27-
28-
func saveLastPushPayload(_ payload: [AnyHashable: Any]?, withExpiration expiration: Date?)
29-
3026
func upgrade()
3127
}
3228

tests/common/MockLocalStorage.swift

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,6 @@ class MockLocalStorage: LocalStorageProtocol {
3333
attributionInfoExpiration = expiration
3434
}
3535

36-
func getLastPushPayload(_ currentDate: Date) -> [AnyHashable : Any]? {
37-
guard !MockLocalStorage.isExpired(expiration: payloadExpiration, currentDate: currentDate) else {
38-
return nil
39-
}
40-
41-
return payload
42-
}
43-
44-
func saveLastPushPayload(_ payload: [AnyHashable : Any]?, withExpiration expiration: Date?) {
45-
self.payload = payload
46-
payloadExpiration = expiration
47-
}
48-
49-
private var payload: [AnyHashable: Any]? = nil
50-
private var payloadExpiration: Date? = nil
51-
5236
private var attributionInfo: IterableAttributionInfo? = nil
5337
private var attributionInfoExpiration: Date? = nil
5438

0 commit comments

Comments
 (0)