Skip to content

Commit ff6c5fa

Browse files
committed
Background flush of operation repo
* When app is backgrounded, flush the operation repo and let each executor and request manage its background task * don't end background tasks until requests return * Processing the queues will take in another flag called `inBackground`
1 parent f9ac55d commit ff6c5fa

File tree

6 files changed

+117
-40
lines changed

6 files changed

+117
-40
lines changed

iOS_SDK/OneSignalSDK/OneSignalOSCore/Source/OSOperationExecutor.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public protocol OSOperationExecutor {
3535

3636
func enqueueDelta(_ delta: OSDelta)
3737
func cacheDeltaQueue()
38-
func processDeltaQueue()
38+
func processDeltaQueue(inBackground: Bool)
3939

40-
func processRequestQueue()
40+
func processRequestQueue(inBackground: Bool)
4141
}

iOS_SDK/OneSignalSDK/OneSignalOSCore/Source/OSOperationRepo.swift

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public class OSOperationRepo: NSObject {
108108
OneSignalUserDefaults.initShared().saveCodeableData(forKey: OS_OPERATION_REPO_DELTA_QUEUE_KEY, withValue: self.deltaQueue)
109109
}
110110

111-
@objc public func flushDeltaQueue() {
111+
@objc public func flushDeltaQueue(inBackground: Bool = false) {
112112
guard !paused else {
113113
OneSignalLog.onesignalLog(.LL_DEBUG, message: "OSOperationRepo not flushing queue due to being paused")
114114
return
@@ -117,9 +117,14 @@ public class OSOperationRepo: NSObject {
117117
guard !OneSignalConfigManager.shouldAwaitAppIdAndLogMissingPrivacyConsent(forMethod: nil) else {
118118
return
119119
}
120+
121+
if (inBackground) {
122+
OSBackgroundTaskManager.beginBackgroundTask(OPERATION_REPO_BACKGROUND_TASK)
123+
}
124+
120125
start()
121126
if !deltaQueue.isEmpty {
122-
OneSignalLog.onesignalLog(.LL_VERBOSE, message: "OSOperationRepo flushDeltaQueue with queue: \(deltaQueue)")
127+
OneSignalLog.onesignalLog(.LL_VERBOSE, message: "OSOperationRepo flushDeltaQueue in background: \(inBackground) with queue: \(deltaQueue)")
123128
}
124129

125130
var index = 0
@@ -141,7 +146,12 @@ public class OSOperationRepo: NSObject {
141146
}
142147

143148
for executor in executors {
144-
executor.processDeltaQueue()
149+
executor.processDeltaQueue(inBackground: inBackground)
145150
}
151+
152+
if (inBackground) {
153+
OSBackgroundTaskManager.endBackgroundTask(OPERATION_REPO_BACKGROUND_TASK)
154+
}
155+
146156
}
147157
}

iOS_SDK/OneSignalSDK/OneSignalUser/Source/OSIdentityOperationExecutor.swift

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class OSIdentityOperationExecutor: OSOperationExecutor {
103103
OneSignalUserDefaults.initShared().saveCodeableData(forKey: OS_IDENTITY_EXECUTOR_DELTA_QUEUE_KEY, withValue: self.deltaQueue)
104104
}
105105

106-
func processDeltaQueue() {
106+
func processDeltaQueue(inBackground: Bool) {
107107
if !deltaQueue.isEmpty {
108108
OneSignalLog.onesignalLog(.LL_VERBOSE, message: "OSIdentityOperationExecutor processDeltaQueue with queue: \(deltaQueue)")
109109
}
@@ -139,10 +139,10 @@ class OSIdentityOperationExecutor: OSOperationExecutor {
139139

140140
OneSignalUserDefaults.initShared().saveCodeableData(forKey: OS_IDENTITY_EXECUTOR_DELTA_QUEUE_KEY, withValue: self.deltaQueue) // This should be empty, can remove instead?
141141

142-
processRequestQueue()
142+
processRequestQueue(inBackground: inBackground)
143143
}
144144

145-
func processRequestQueue() {
145+
func processRequestQueue(inBackground: Bool) {
146146
let requestQueue: [OneSignalRequest] = addRequestQueue + removeRequestQueue
147147

148148
if requestQueue.isEmpty {
@@ -154,16 +154,16 @@ class OSIdentityOperationExecutor: OSOperationExecutor {
154154
return first.timestamp < second.timestamp
155155
}) {
156156
if request.isKind(of: OSRequestAddAliases.self), let addAliasesRequest = request as? OSRequestAddAliases {
157-
executeAddAliasesRequest(addAliasesRequest)
157+
executeAddAliasesRequest(addAliasesRequest, inBackground: inBackground)
158158
} else if request.isKind(of: OSRequestRemoveAlias.self), let removeAliasRequest = request as? OSRequestRemoveAlias {
159-
executeRemoveAliasRequest(removeAliasRequest)
159+
executeRemoveAliasRequest(removeAliasRequest, inBackground: inBackground)
160160
} else {
161161
OneSignalLog.onesignalLog(.LL_DEBUG, message: "OSIdentityOperationExecutor.processRequestQueue met incompatible OneSignalRequest type: \(request).")
162162
}
163163
}
164164
}
165165

166-
func executeAddAliasesRequest(_ request: OSRequestAddAliases) {
166+
func executeAddAliasesRequest(_ request: OSRequestAddAliases, inBackground: Bool) {
167167
guard !request.sentToClient else {
168168
return
169169
}
@@ -174,11 +174,19 @@ class OSIdentityOperationExecutor: OSOperationExecutor {
174174

175175
OneSignalLog.onesignalLog(.LL_VERBOSE, message: "OSIdentityOperationExecutor: executeAddAliasesRequest making request: \(request)")
176176

177+
let backgroundTaskIdentifier = IDENTITY_EXECUTOR_BACKGROUND_TASK + UUID().uuidString
178+
if (inBackground) {
179+
OSBackgroundTaskManager.beginBackgroundTask(backgroundTaskIdentifier)
180+
}
181+
177182
OneSignalClient.shared().execute(request) { _ in
178183
// No hydration from response
179184
// On success, remove request from cache
180185
self.addRequestQueue.removeAll(where: { $0 == request})
181186
OneSignalUserDefaults.initShared().saveCodeableData(forKey: OS_IDENTITY_EXECUTOR_ADD_REQUEST_QUEUE_KEY, withValue: self.addRequestQueue)
187+
if (inBackground) {
188+
OSBackgroundTaskManager.endBackgroundTask(backgroundTaskIdentifier)
189+
}
182190
} onFailure: { error in
183191
OneSignalLog.onesignalLog(.LL_ERROR, message: "OSIdentityOperationExecutor add aliases request failed with error: \(error.debugDescription)")
184192
if let nsError = error as? NSError {
@@ -190,6 +198,9 @@ class OSIdentityOperationExecutor: OSOperationExecutor {
190198
// Logout if the user in the SDK is the same
191199
guard OneSignalUserManagerImpl.sharedInstance.isCurrentUser(request.identityModel)
192200
else {
201+
if (inBackground) {
202+
OSBackgroundTaskManager.endBackgroundTask(backgroundTaskIdentifier)
203+
}
193204
return
194205
}
195206
// The subscription has been deleted along with the user, so remove the subscription_id but keep the same push subscription model
@@ -210,10 +221,13 @@ class OSIdentityOperationExecutor: OSOperationExecutor {
210221
OneSignalUserDefaults.initShared().saveCodeableData(forKey: OS_IDENTITY_EXECUTOR_ADD_REQUEST_QUEUE_KEY, withValue: self.addRequestQueue)
211222
}
212223
}
224+
if (inBackground) {
225+
OSBackgroundTaskManager.endBackgroundTask(backgroundTaskIdentifier)
226+
}
213227
}
214228
}
215229

216-
func executeRemoveAliasRequest(_ request: OSRequestRemoveAlias) {
230+
func executeRemoveAliasRequest(_ request: OSRequestRemoveAlias, inBackground: Bool) {
217231
guard !request.sentToClient else {
218232
return
219233
}
@@ -224,11 +238,19 @@ class OSIdentityOperationExecutor: OSOperationExecutor {
224238

225239
OneSignalLog.onesignalLog(.LL_VERBOSE, message: "OSIdentityOperationExecutor: executeRemoveAliasRequest making request: \(request)")
226240

241+
let backgroundTaskIdentifier = IDENTITY_EXECUTOR_BACKGROUND_TASK + UUID().uuidString
242+
if (inBackground) {
243+
OSBackgroundTaskManager.beginBackgroundTask(backgroundTaskIdentifier)
244+
}
245+
227246
OneSignalClient.shared().execute(request) { _ in
228247
// There is nothing to hydrate
229248
// On success, remove request from cache
230249
self.removeRequestQueue.removeAll(where: { $0 == request})
231250
OneSignalUserDefaults.initShared().saveCodeableData(forKey: OS_IDENTITY_EXECUTOR_REMOVE_REQUEST_QUEUE_KEY, withValue: self.removeRequestQueue)
251+
if (inBackground) {
252+
OSBackgroundTaskManager.endBackgroundTask(backgroundTaskIdentifier)
253+
}
232254
} onFailure: { error in
233255
OneSignalLog.onesignalLog(.LL_ERROR, message: "OSIdentityOperationExecutor remove alias request failed with error: \(error.debugDescription)")
234256

@@ -241,6 +263,9 @@ class OSIdentityOperationExecutor: OSOperationExecutor {
241263
OneSignalUserDefaults.initShared().saveCodeableData(forKey: OS_IDENTITY_EXECUTOR_REMOVE_REQUEST_QUEUE_KEY, withValue: self.removeRequestQueue)
242264
}
243265
}
266+
if (inBackground) {
267+
OSBackgroundTaskManager.endBackgroundTask(backgroundTaskIdentifier)
268+
}
244269
}
245270
}
246271
}

iOS_SDK/OneSignalSDK/OneSignalUser/Source/OSPropertyOperationExecutor.swift

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class OSPropertyOperationExecutor: OSOperationExecutor {
8686
OneSignalUserDefaults.initShared().saveCodeableData(forKey: OS_PROPERTIES_EXECUTOR_DELTA_QUEUE_KEY, withValue: self.deltaQueue)
8787
}
8888

89-
func processDeltaQueue() {
89+
func processDeltaQueue(inBackground: Bool) {
9090
if !deltaQueue.isEmpty {
9191
OneSignalLog.onesignalLog(.LL_VERBOSE, message: "OSPropertyOperationExecutor processDeltaQueue with queue: \(deltaQueue)")
9292
}
@@ -111,33 +111,41 @@ class OSPropertyOperationExecutor: OSOperationExecutor {
111111
OneSignalUserDefaults.initShared().saveCodeableData(forKey: OS_PROPERTIES_EXECUTOR_UPDATE_REQUEST_QUEUE_KEY, withValue: self.updateRequestQueue)
112112

113113
OneSignalUserDefaults.initShared().saveCodeableData(forKey: OS_PROPERTIES_EXECUTOR_DELTA_QUEUE_KEY, withValue: self.deltaQueue) // This should be empty, can remove instead?
114-
processRequestQueue()
114+
processRequestQueue(inBackground: inBackground)
115115
}
116116

117-
func processRequestQueue() {
117+
func processRequestQueue(inBackground: Bool) {
118118
if updateRequestQueue.isEmpty {
119119
return
120120
}
121121

122122
for request in updateRequestQueue {
123-
executeUpdatePropertiesRequest(request)
123+
executeUpdatePropertiesRequest(request, inBackground: inBackground)
124124
}
125125
}
126126

127-
func executeUpdatePropertiesRequest(_ request: OSRequestUpdateProperties) {
127+
func executeUpdatePropertiesRequest(_ request: OSRequestUpdateProperties, inBackground: Bool) {
128128
guard !request.sentToClient else {
129129
return
130130
}
131131
guard request.prepareForExecution() else {
132132
return
133133
}
134134
request.sentToClient = true
135-
135+
136+
let backgroundTaskIdentifier = PROPERTIES_EXECUTOR_BACKGROUND_TASK + UUID().uuidString
137+
if (inBackground) {
138+
OSBackgroundTaskManager.beginBackgroundTask(backgroundTaskIdentifier)
139+
}
140+
136141
OneSignalClient.shared().execute(request) { _ in
137142
// On success, remove request from cache, and we do need to hydrate
138143
// TODO: We need to hydrate after all ? What why ?
139144
self.updateRequestQueue.removeAll(where: { $0 == request})
140145
OneSignalUserDefaults.initShared().saveCodeableData(forKey: OS_PROPERTIES_EXECUTOR_UPDATE_REQUEST_QUEUE_KEY, withValue: self.updateRequestQueue)
146+
if (inBackground) {
147+
OSBackgroundTaskManager.endBackgroundTask(backgroundTaskIdentifier)
148+
}
141149
} onFailure: { error in
142150
OneSignalLog.onesignalLog(.LL_ERROR, message: "OSPropertyOperationExecutor update properties request failed with error: \(error.debugDescription)")
143151
if let nsError = error as? NSError {
@@ -149,6 +157,9 @@ class OSPropertyOperationExecutor: OSOperationExecutor {
149157
// Logout if the user in the SDK is the same
150158
guard OneSignalUserManagerImpl.sharedInstance.isCurrentUser(request.identityModel)
151159
else {
160+
if (inBackground) {
161+
OSBackgroundTaskManager.endBackgroundTask(backgroundTaskIdentifier)
162+
}
152163
return
153164
}
154165
// The subscription has been deleted along with the user, so remove the subscription_id but keep the same push subscription model
@@ -160,6 +171,9 @@ class OSPropertyOperationExecutor: OSOperationExecutor {
160171
OneSignalUserDefaults.initShared().saveCodeableData(forKey: OS_PROPERTIES_EXECUTOR_UPDATE_REQUEST_QUEUE_KEY, withValue: self.updateRequestQueue)
161172
}
162173
}
174+
if (inBackground) {
175+
OSBackgroundTaskManager.endBackgroundTask(backgroundTaskIdentifier)
176+
}
163177
}
164178
}
165179
}

0 commit comments

Comments
 (0)