Skip to content

Commit 9ed3cdd

Browse files
authored
Merge pull request #849 from Iterable/feature/MOB-9746-Use-destinationUser-JWT-when-calling-merge
Added support for fetching new JWT prior to calling merge
2 parents 9a26368 + 49eb8f3 commit 9ed3cdd

File tree

7 files changed

+515
-56
lines changed

7 files changed

+515
-56
lines changed

sample-apps/swift-sample-app/swift-sample-app/AppDelegate.swift

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,28 @@ import UserNotifications
1212
import IterableSDK
1313

1414
@UIApplicationMain
15-
class AppDelegate: UIResponder, UIApplicationDelegate {
15+
class AppDelegate: UIResponder, UIApplicationDelegate, IterableAuthDelegate {
16+
func onAuthTokenRequested(completion: @escaping IterableSDK.AuthTokenRetrievalHandler) {
17+
// ITBL: Set your actual secret.
18+
let jwt = IterableTokenGenerator.generateJwtForUserId(
19+
secret: "",
20+
iat: Int(Date().timeIntervalSince1970),
21+
exp: Int(Date().timeIntervalSince1970) + (24*60),
22+
userId: IterableAPI.userId ?? "")
23+
print(jwt)
24+
completion(jwt)
25+
}
26+
27+
28+
func onAuthFailure(_ authFailure: IterableSDK.AuthFailure) {
29+
30+
}
31+
1632
var window: UIWindow?
1733

1834
// ITBL: Set your actual api key here.
1935
let iterableApiKey = ""
20-
36+
2137
func application(_: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
2238
// ITBL: Setup Notification
2339
setupNotifications()
@@ -28,6 +44,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
2844
config.urlDelegate = self
2945
config.inAppDisplayInterval = 1
3046
config.anonUserDelegate = self
47+
config.enableAnonTracking = true
48+
config.authDelegate = self
3149
IterableAPI.initialize(apiKey: iterableApiKey,
3250
launchOptions: launchOptions,
3351
config: config)
@@ -177,3 +195,4 @@ extension AppDelegate: IterableCustomActionDelegate {
177195
return false
178196
}
179197
}
198+

sample-apps/swift-sample-app/swift-sample-app/CoffeeListTableViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class CoffeeListTableViewController: UITableViewController {
7474
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
7575
if indexPath.section == 0 {
7676
let cell = tableView.dequeueReusableCell(withIdentifier: "anonymousUsageTrackCell", for: indexPath)
77-
cell.textLabel?.text = IterableAPI.getAnonymousUsageTracked() ? "Tap to enable Anonymous Usage Track" : "Tap to disable Anonymous Usage Track"
77+
cell.textLabel?.text = IterableAPI.getAnonymousUsageTracked() ? "Tap to disable Anonymous Usage Track" : "Tap to enable Anonymous Usage Track"
7878
cell.textLabel?.numberOfLines = 0
7979
cell.accessoryType = IterableAPI.getAnonymousUsageTracked() ? .checkmark : .none
8080
return cell

swift-sdk.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
18A3520C2C85BAF0007FED53 /* IsOneOfInNotOneOfCriteareaTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18A3520B2C85BAF0007FED53 /* IsOneOfInNotOneOfCriteareaTest.swift */; };
2222
18BB8B7A2C64DC8D007EBF23 /* ComparatorTypeDoesNotEqualMatchTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18BB8B792C64DC8D007EBF23 /* ComparatorTypeDoesNotEqualMatchTest.swift */; };
2323
18E23AE02C6CDE97002B2D92 /* CombinationLogicEventTypeCriteria.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18E23ADF2C6CDE97002B2D92 /* CombinationLogicEventTypeCriteria.swift */; };
24+
18E5B5D12CC77BCE00A558EC /* IterableTokenGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18E5B5D02CC77BCE00A558EC /* IterableTokenGenerator.swift */; };
25+
18E5B5D32CC7853D00A558EC /* ValidateTokenForDestinationUserTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18E5B5D22CC7853D00A558EC /* ValidateTokenForDestinationUserTest.swift */; };
2426
1CBFFE1A2A97AEEF00ED57EE /* EmbeddedManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CBFFE162A97AEEE00ED57EE /* EmbeddedManagerTests.swift */; };
2527
1CBFFE1B2A97AEEF00ED57EE /* EmbeddedMessagingProcessorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CBFFE172A97AEEE00ED57EE /* EmbeddedMessagingProcessorTests.swift */; };
2628
1CBFFE1C2A97AEEF00ED57EE /* EmbeddedSessionManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CBFFE182A97AEEE00ED57EE /* EmbeddedSessionManagerTests.swift */; };
@@ -579,6 +581,8 @@
579581
18A3520B2C85BAF0007FED53 /* IsOneOfInNotOneOfCriteareaTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IsOneOfInNotOneOfCriteareaTest.swift; sourceTree = "<group>"; };
580582
18BB8B792C64DC8D007EBF23 /* ComparatorTypeDoesNotEqualMatchTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComparatorTypeDoesNotEqualMatchTest.swift; sourceTree = "<group>"; };
581583
18E23ADF2C6CDE97002B2D92 /* CombinationLogicEventTypeCriteria.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CombinationLogicEventTypeCriteria.swift; sourceTree = "<group>"; };
584+
18E5B5D02CC77BCE00A558EC /* IterableTokenGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IterableTokenGenerator.swift; sourceTree = "<group>"; };
585+
18E5B5D22CC7853D00A558EC /* ValidateTokenForDestinationUserTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValidateTokenForDestinationUserTest.swift; sourceTree = "<group>"; };
582586
1CBFFE162A97AEEE00ED57EE /* EmbeddedManagerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmbeddedManagerTests.swift; sourceTree = "<group>"; };
583587
1CBFFE172A97AEEE00ED57EE /* EmbeddedMessagingProcessorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmbeddedMessagingProcessorTests.swift; sourceTree = "<group>"; };
584588
1CBFFE182A97AEEE00ED57EE /* EmbeddedSessionManagerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmbeddedSessionManagerTests.swift; sourceTree = "<group>"; };
@@ -1105,6 +1109,7 @@
11051109
AC72A0BF20CF4CB8004D7997 /* IterableAction.swift */,
11061110
ACF560E720E55A6B000AAC23 /* IterableActionContext.swift */,
11071111
AC6FDD8720F4372E005D811E /* IterableAPI.swift */,
1112+
18E5B5D02CC77BCE00A558EC /* IterableTokenGenerator.swift */,
11081113
AC72A0C620CF4CB9004D7997 /* IterableAppIntegration.swift */,
11091114
AC72A0C020CF4CB8004D7997 /* IterableAttributionInfo.swift */,
11101115
55DD207E26A0D83800773CC7 /* IterableAuthManagerProtocol.swift */,
@@ -1701,6 +1706,7 @@
17011706
181063DC2C994FA40078E0ED /* ValidateCustomEventUserUpdateAPITest.swift */,
17021707
181063DE2C9D51000078E0ED /* ValidateStoredEventCheckUnknownToKnownUserTest.swift */,
17031708
1802C00E2CA2C99E009DEA2B /* CombinationComplexCriteria.swift */,
1709+
18E5B5D22CC7853D00A558EC /* ValidateTokenForDestinationUserTest.swift */,
17041710
);
17051711
name = "anonymous-tracking-tests";
17061712
sourceTree = "<group>";
@@ -2216,6 +2222,7 @@
22162222
5555425028BED1B400DB5D20 /* KeychainWrapper.swift in Sources */,
22172223
9F0616412C9CA9D400FE2E6A /* IterableIdentityResolution.swift in Sources */,
22182224
AC81918A22713A400014955E /* AbstractDiffCalculator.swift in Sources */,
2225+
18E5B5D12CC77BCE00A558EC /* IterableTokenGenerator.swift in Sources */,
22192226
ACA95D2D275494A100AF4666 /* InboxViewRepresentable.swift in Sources */,
22202227
AC684A88222F4FDD00F29749 /* InAppDisplayer.swift in Sources */,
22212228
AC72A0D220CF4D12004D7997 /* IterableUtil.swift in Sources */,
@@ -2370,6 +2377,7 @@
23702377
5588DFA928C045AE000697D7 /* MockInAppFetcher.swift in Sources */,
23712378
55CC257B2462064F00A77FD5 /* InAppPresenterTests.swift in Sources */,
23722379
AC4BA00224163D8F007359F1 /* IterableHtmlMessageViewControllerTests.swift in Sources */,
2380+
18E5B5D32CC7853D00A558EC /* ValidateTokenForDestinationUserTest.swift in Sources */,
23732381
55B37FC822975A840042F13A /* InboxMessageViewModelTests.swift in Sources */,
23742382
182A2A152C661C9A002FF058 /* DataTypeComparatorSearchQueryCriteria.swift in Sources */,
23752383
55E6F462238E066400808BCE /* DeepLinkTests.swift in Sources */,

swift-sdk/Internal/AuthManager.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,15 +161,19 @@ class AuthManager: IterableAuthManagerProtocol {
161161
let isRefreshQueued = queueAuthTokenExpirationRefresh(retrievedAuthToken, onSuccess: onSuccess)
162162
if !isRefreshQueued {
163163
onSuccess?(authToken)
164+
authToken = retrievedAuthToken
165+
storeAuthToken()
166+
} else {
167+
authToken = retrievedAuthToken
168+
storeAuthToken()
169+
onSuccess?(authToken)
164170
}
165171
} else {
166172
handleAuthFailure(failedAuthToken: nil, reason: .authTokenNull)
167173
scheduleAuthTokenRefreshTimer(interval: getNextRetryInterval(), successCallback: onSuccess)
174+
authToken = retrievedAuthToken
175+
storeAuthToken()
168176
}
169-
170-
authToken = retrievedAuthToken
171-
172-
storeAuthToken()
173177
}
174178

175179
func handleAuthFailure(failedAuthToken: String?, reason: AuthFailureReason) {

swift-sdk/Internal/InternalIterableAPI.swift

Lines changed: 59 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -133,83 +133,90 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider {
133133
func setEmail(_ email: String?, authToken: String? = nil, successHandler: OnSuccessHandler? = nil, failureHandler: OnFailureHandler? = nil, identityResolution: IterableIdentityResolution? = nil) {
134134

135135
ITBInfo()
136-
137-
let merge = identityResolution?.mergeOnAnonymousToKnown ?? config.identityResolution.mergeOnAnonymousToKnown
138-
let replay = identityResolution?.replayOnVisitorToKnown ?? config.identityResolution.replayOnVisitorToKnown
139-
140136
if self._email == email && email != nil {
141137
self.checkAndUpdateAuthToken(authToken)
142138
return
143139
}
144-
140+
145141
if self._email == email {
146142
return
147143
}
148144

149145
self.logoutPreviousUser()
150-
146+
151147
self._email = email
152148
self._userId = nil
153-
154-
if config.enableAnonTracking, let email = email {
155-
attemptAndProcessMerge(
156-
merge: merge ?? true,
157-
replay: replay ?? true,
158-
destinationUser: email,
159-
isEmail: true,
160-
failureHandler: failureHandler
161-
)
162-
self.localStorage.userIdAnnon = nil
149+
150+
self.onLogin(authToken) { [weak self] in
151+
guard let config = self?.config else {
152+
return
153+
}
154+
let merge = identityResolution?.mergeOnAnonymousToKnown ?? config.identityResolution.mergeOnAnonymousToKnown
155+
let replay = identityResolution?.replayOnVisitorToKnown ?? config.identityResolution.replayOnVisitorToKnown
156+
if config.enableAnonTracking, let email = email {
157+
self?.attemptAndProcessMerge(
158+
merge: merge ?? true,
159+
replay: replay ?? true,
160+
destinationUser: email,
161+
isEmail: true,
162+
failureHandler: failureHandler
163+
)
164+
self?.localStorage.userIdAnnon = nil
165+
}
163166
}
167+
168+
164169
self._successCallback = successHandler
165170
self._failureCallback = failureHandler
166171
self.storeIdentifierData()
167-
self.onLogin(authToken)
168-
169172
}
170173

171174
func setUserId(_ userId: String?, authToken: String? = nil, successHandler: OnSuccessHandler? = nil, failureHandler: OnFailureHandler? = nil, isAnon: Bool = false, identityResolution: IterableIdentityResolution? = nil) {
172175
ITBInfo()
173-
174-
let merge = identityResolution?.mergeOnAnonymousToKnown ?? config.identityResolution.mergeOnAnonymousToKnown
175-
let replay = identityResolution?.replayOnVisitorToKnown ?? config.identityResolution.replayOnVisitorToKnown
176-
176+
177177
if self._userId == userId && userId != nil {
178178
self.checkAndUpdateAuthToken(authToken)
179179
return
180180
}
181-
181+
182182
if self._userId == userId {
183183
return
184184
}
185-
185+
186186
self.logoutPreviousUser()
187-
187+
188188
self._email = nil
189189
self._userId = userId
190190

191-
if config.enableAnonTracking {
192-
if let userId = userId, userId != localStorage.userIdAnnon {
193-
attemptAndProcessMerge(
194-
merge: merge ?? true,
195-
replay: replay ?? true,
196-
destinationUser: userId,
197-
isEmail: false,
198-
failureHandler: failureHandler
199-
)
191+
self.onLogin(authToken) { [weak self] in
192+
guard let config = self?.config else {
193+
return
200194
}
201-
202-
if !isAnon {
203-
localStorage.userIdAnnon = nil
195+
if config.enableAnonTracking {
196+
if let userId = userId, userId != (self?.localStorage.userIdAnnon ?? "") {
197+
let merge = identityResolution?.mergeOnAnonymousToKnown ?? config.identityResolution.mergeOnAnonymousToKnown
198+
let replay = identityResolution?.replayOnVisitorToKnown ?? config.identityResolution.replayOnVisitorToKnown
199+
self?.attemptAndProcessMerge(
200+
merge: merge ?? true,
201+
replay: replay ?? true,
202+
destinationUser: userId,
203+
isEmail: false,
204+
failureHandler: failureHandler
205+
)
206+
}
207+
208+
if !isAnon {
209+
self?.localStorage.userIdAnnon = nil
210+
}
204211
}
205212
}
206-
213+
207214
self._successCallback = successHandler
208215
self._failureCallback = failureHandler
209216
self.storeIdentifierData()
210-
self.onLogin(authToken)
217+
211218
}
212-
219+
213220
func logoutUser() {
214221
logoutPreviousUser()
215222
}
@@ -233,6 +240,7 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider {
233240
self.localStorage.anonymousUserEvents = nil
234241
self.localStorage.anonymousSessions = nil
235242
self.localStorage.anonymousUserUpdate = nil
243+
self.localStorage.userIdAnnon = nil
236244

237245
if isAnonymousUsageTracked && config.enableAnonTracking {
238246
ITBInfo("CONSENT GIVEN and ANON TRACKING ENABLED - Criteria fetched")
@@ -738,35 +746,34 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider {
738746
localStorage.userId = _userId
739747
}
740748

741-
private func onLogin(_ authToken: String? = nil) {
749+
private func onLogin(_ authToken: String? = nil, onloginSuccess onloginSuccessCallBack: (()->())? = nil) {
742750
guard isSDKInitialized() else { return }
743751

744752
ITBInfo()
745753

746754
self.authManager.pauseAuthRetries(false)
747755
if let authToken {
748756
self.authManager.setNewToken(authToken)
749-
completeUserLogin()
757+
completeUserLogin(onloginSuccessCallBack: onloginSuccessCallBack)
750758
} else if isEitherUserIdOrEmailSet() && config.authDelegate != nil {
751-
requestNewAuthToken()
759+
requestNewAuthToken(onloginSuccessCallBack: onloginSuccessCallBack)
752760
} else {
753-
completeUserLogin()
761+
completeUserLogin(onloginSuccessCallBack: onloginSuccessCallBack)
754762
}
755763
}
756764

757-
private func requestNewAuthToken() {
765+
private func requestNewAuthToken(onloginSuccessCallBack: (()->())? = nil) {
758766
ITBInfo()
759767

760768
authManager.requestNewAuthToken(hasFailedPriorAuth: false, onSuccess: { [weak self] token in
761769
if token != nil {
762-
self?.completeUserLogin()
770+
self?.completeUserLogin(onloginSuccessCallBack: onloginSuccessCallBack)
763771
}
764772
}, shouldIgnoreRetryPolicy: true)
765773
}
766774

767-
private func completeUserLogin() {
768-
ITBInfo()
769-
775+
private func completeUserLogin(onloginSuccessCallBack: (()->())? = nil) {
776+
ITBInfo()
770777
guard isSDKInitialized() else { return }
771778

772779
if config.autoPushRegistration {
@@ -776,6 +783,9 @@ final class InternalIterableAPI: NSObject, PushTrackerProtocol, AuthProvider {
776783
}
777784

778785
_ = inAppManager.scheduleSync()
786+
if onloginSuccessCallBack != nil {
787+
onloginSuccessCallBack!()
788+
}
779789
}
780790

781791
private func retrieveIdentifierData() {

0 commit comments

Comments
 (0)