Skip to content

Commit 9820ffb

Browse files
Merge branch 'master' into offline-events
# Conflicts: # swift-sdk/Internal/IterableAPIInternal.swift # swift-sdk/IterableConfig.swift
2 parents a79e284 + 45635ce commit 9820ffb

File tree

9 files changed

+221
-56
lines changed

9 files changed

+221
-56
lines changed

.github/workflows/build-and-test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: Build and test
33
on: pull_request
44

55
jobs:
6-
build:
6+
run-tests-job:
77
runs-on: macos-latest
88

99
steps:
@@ -15,7 +15,7 @@ jobs:
1515

1616
- name: Build and test
1717
run: |
18-
xcodebuild test -project swift-sdk.xcodeproj -scheme swift-sdk -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 11' -enableCodeCoverage YES CODE_SIGNING_REQUIRED=NO | xcpretty || exit 1
18+
xcodebuild test -project swift-sdk.xcodeproj -scheme swift-sdk -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 11' -enableCodeCoverage YES CODE_SIGNING_REQUIRED=NO | xcpretty && exit ${PIPESTATUS[0]}
1919
2020
- name: CocoaPods lint
2121
run: pod lib lint

.github/workflows/e2e.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: Integration Testing
33
on: pull_request
44

55
jobs:
6-
build:
6+
run-e2e-job:
77
runs-on: macos-latest
88

99
steps:

swift-sdk.xcodeproj/project.pbxproj

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,6 @@
541541
ACFD5AC524C8216A008E497A /* TasksCRUDTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TasksCRUDTests.swift; sourceTree = "<group>"; };
542542
ACFD5AC724C8290E008E497A /* IterableTaskManagedObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IterableTaskManagedObject.swift; sourceTree = "<group>"; };
543543
ACFF429E24656BDF00FDF10D /* ui-tests-app.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ui-tests-app.app"; sourceTree = BUILT_PRODUCTS_DIR; };
544-
ACFF429F24656BDF00FDF10D /* host-app copy-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "host-app copy-Info.plist"; path = "/Users/tapash.majumder/work/iterable/mobile/ios/swift-sdk/host-app copy-Info.plist"; sourceTree = "<absolute>"; };
545544
ACFF42A324656CA100FDF10D /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
546545
ACFF42A624656D2600FDF10D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
547546
ACFF42A824656D8E00FDF10D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
@@ -717,7 +716,6 @@
717716
ACDA975A23159C37004C412E /* inbox-ui-tests-app */,
718717
ACFCA72920EB02DB00BFB277 /* tests */,
719718
5550F22324217CFC0014456A /* misc */,
720-
ACFF429F24656BDF00FDF10D /* host-app copy-Info.plist */,
721719
);
722720
sourceTree = "<group>";
723721
};

swift-sdk/Internal/AuthManager.swift

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,20 @@ import Foundation
77

88
@objc public protocol IterableInternalAuthManagerProtocol {
99
func getAuthToken() -> String?
10-
func requestNewAuthToken()
10+
func requestNewAuthToken(hasFailedPriorAuth: Bool, onSuccess: (() -> Void)?)
1111
func logoutUser()
1212
}
1313

1414
class AuthManager: IterableInternalAuthManagerProtocol {
1515
init(onAuthTokenRequestedCallback: (() -> String?)?,
16+
refreshWindow: TimeInterval,
1617
localStorage: LocalStorageProtocol,
17-
refreshWindow: TimeInterval = AuthManager.defaultRefreshWindow) {
18+
dateProvider: DateProviderProtocol) {
1819
ITBInfo()
1920

2021
self.onAuthTokenRequestedCallback = onAuthTokenRequestedCallback
2122
self.localStorage = localStorage
23+
self.dateProvider = dateProvider
2224
self.refreshWindow = refreshWindow
2325

2426
retrieveAuthToken()
@@ -35,11 +37,21 @@ class AuthManager: IterableInternalAuthManagerProtocol {
3537
}
3638

3739
// @objc attribute only needed for the pre-iOS 10 Timer constructor in queueAuthTokenExpirationRefresh
38-
@objc func requestNewAuthToken() {
40+
@objc func requestNewAuthToken(hasFailedPriorAuth: Bool = false, onSuccess: (() -> Void)? = nil) {
41+
guard !self.hasFailedPriorAuth || !hasFailedPriorAuth else {
42+
return
43+
}
44+
45+
self.hasFailedPriorAuth = hasFailedPriorAuth
46+
3947
authToken = onAuthTokenRequestedCallback?()
4048

4149
storeAuthToken()
4250

51+
if authToken != nil {
52+
onSuccess?()
53+
}
54+
4355
queueAuthTokenExpirationRefresh(authToken)
4456
}
4557

@@ -49,48 +61,46 @@ class AuthManager: IterableInternalAuthManagerProtocol {
4961
storeAuthToken()
5062

5163
expirationRefreshTimer?.invalidate()
52-
}
53-
54-
// MARK: - Auth Manager Functions
55-
56-
func storeAuthToken() {
57-
localStorage.authToken = authToken
58-
}
59-
60-
func retrieveAuthToken() {
61-
authToken = localStorage.authToken
62-
63-
queueAuthTokenExpirationRefresh(authToken)
64+
expirationRefreshTimer = nil
6465
}
6566

6667
// MARK: - Private/Internal
6768

68-
private let refreshWindow: TimeInterval
69-
7069
private var expirationRefreshTimer: Timer?
7170

7271
private var authToken: String?
7372

74-
private var localStorage: LocalStorageProtocol
73+
private var hasFailedPriorAuth: Bool = false
7574

7675
private let onAuthTokenRequestedCallback: (() -> String?)?
76+
private let refreshWindow: TimeInterval
77+
private var localStorage: LocalStorageProtocol
78+
private let dateProvider: DateProviderProtocol
79+
80+
private func storeAuthToken() {
81+
localStorage.authToken = authToken
82+
}
7783

78-
static let defaultRefreshWindow: TimeInterval = 60
84+
private func retrieveAuthToken() {
85+
authToken = localStorage.authToken
86+
87+
queueAuthTokenExpirationRefresh(authToken)
88+
}
7989

8090
private func queueAuthTokenExpirationRefresh(_ authToken: String?) {
8191
guard let authToken = authToken, let expirationDate = AuthManager.decodeExpirationDateFromAuthToken(authToken) else {
8292
return
8393
}
8494

85-
let refreshTimeInterval = TimeInterval(expirationDate) - Date().timeIntervalSince1970 - refreshWindow
95+
let timeIntervalToRefresh = TimeInterval(expirationDate) - dateProvider.currentDate.timeIntervalSince1970 - refreshWindow
8696

8797
if #available(iOS 10.0, *) {
88-
expirationRefreshTimer = Timer.scheduledTimer(withTimeInterval: refreshTimeInterval, repeats: false) { timer in
89-
self.requestNewAuthToken()
98+
expirationRefreshTimer = Timer.scheduledTimer(withTimeInterval: timeIntervalToRefresh, repeats: false) { [weak self] _ in
99+
self?.requestNewAuthToken(hasFailedPriorAuth: false)
90100
}
91101
} else {
92102
// Fallback on earlier versions
93-
expirationRefreshTimer = Timer.scheduledTimer(timeInterval: refreshTimeInterval,
103+
expirationRefreshTimer = Timer.scheduledTimer(timeInterval: timeIntervalToRefresh,
94104
target: self,
95105
selector: #selector(requestNewAuthToken),
96106
userInfo: nil,

swift-sdk/Internal/DependencyContainer.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,11 @@ extension DependencyContainerProtocol {
4141
retryInterval: config.inAppDisplayInterval)
4242
}
4343

44-
func createAuthManager(config: IterableConfig,
45-
localStorage: LocalStorageProtocol) -> IterableInternalAuthManagerProtocol {
44+
func createAuthManager(config: IterableConfig) -> IterableInternalAuthManagerProtocol {
4645
AuthManager(onAuthTokenRequestedCallback: config.onAuthTokenRequestedCallback,
47-
localStorage: localStorage)
46+
refreshWindow: config.authTokenRefreshWindow,
47+
localStorage: localStorage,
48+
dateProvider: dateProvider)
4849
}
4950
}
5051

swift-sdk/Internal/IterableAPIInternal.swift

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,7 @@ final class IterableAPIInternal: NSObject, PushTrackerProtocol, AuthProvider {
6868
}()
6969

7070
lazy var authManager: IterableInternalAuthManagerProtocol = {
71-
self.dependencyContainer.createAuthManager(config: self.config,
72-
localStorage: self.localStorage)
71+
self.dependencyContainer.createAuthManager(config: self.config)
7372
}()
7473

7574
// MARK: - SDK Functions
@@ -99,7 +98,9 @@ final class IterableAPIInternal: NSObject, PushTrackerProtocol, AuthProvider {
9998
_email = email
10099
_userId = nil
101100

102-
authManager.requestNewAuthToken()
101+
authManager.requestNewAuthToken(hasFailedPriorAuth: false) { [weak self] in
102+
self?.loginNewUser()
103+
}
103104

104105
storeIdentifierData()
105106

@@ -114,7 +115,9 @@ final class IterableAPIInternal: NSObject, PushTrackerProtocol, AuthProvider {
114115
_email = nil
115116
_userId = userId
116117

117-
authManager.requestNewAuthToken()
118+
authManager.requestNewAuthToken(hasFailedPriorAuth: false) { [weak self] in
119+
self?.loginNewUser()
120+
}
118121

119122
storeIdentifierData()
120123

@@ -485,18 +488,6 @@ final class IterableAPIInternal: NSObject, PushTrackerProtocol, AuthProvider {
485488
}
486489
}
487490

488-
@discardableResult
489-
private static func call(successHandler onSuccess: OnSuccessHandler? = nil,
490-
andFailureHandler onFailure: OnFailureHandler? = nil,
491-
forResult result: Future<SendRequestValue, SendRequestError>) -> Future<SendRequestValue, SendRequestError> {
492-
result.onSuccess { json in
493-
onSuccess?(json)
494-
}.onError { error in
495-
onFailure?(error.reason, error.data)
496-
}
497-
return result
498-
}
499-
500491
// package private method. Do not call this directly.
501492
init(apiKey: String,
502493
launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil,

swift-sdk/Internal/RequestProcessorUtil.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct RequestProcessorUtil {
2121
}.onError { error in
2222
if error.httpStatusCode == 401, error.iterableCode == JsonValue.Code.invalidJwtPayload {
2323
ITBError(error.reason)
24-
authManager?.requestNewAuthToken()
24+
authManager?.requestNewAuthToken(hasFailedPriorAuth: true, onSuccess: nil)
2525
} else if error.httpStatusCode == 401, error.iterableCode == JsonValue.Code.badApiKey {
2626
ITBError(error.reason)
2727
}

swift-sdk/IterableConfig.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ public class IterableConfig: NSObject {
120120
/// How many seconds to wait before showing the next in-app, if there are more than one present
121121
public var inAppDisplayInterval: Double = 30.0
122122

123+
/// the number of seconds before expiration of the auth token to get a new auth token
124+
public var authTokenRefreshWindow: TimeInterval = 60.0
125+
123126
/// If set to true, events will be queued locally when network is offline.
124127
/// When the network is online again, the queued events will be sent to our backend.
125128
public var enableOfflineMode = false

0 commit comments

Comments
 (0)