@@ -35,7 +35,9 @@ import OneSignalCore
3535public class OSOperationRepo : NSObject {
3636 public static let sharedInstance = OSOperationRepo ( )
3737 private var hasCalledStart = false
38- private let deltaQueueLock = UnfairLock ( )
38+
39+ // The Operation Repo dispatch queue, serial. This synchronizes access to `deltaQueue` and flushing behavior.
40+ private let dispatchQueue = DispatchQueue ( label: " OneSignal.OSOperationRepo " , target: . global( ) )
3941
4042 // Maps delta names to the interfaces for the operation executors
4143 var deltasToExecutorMap : [ String : OSOperationExecutor ] = [ : ]
@@ -63,7 +65,7 @@ public class OSOperationRepo: NSObject {
6365 OneSignalLog . onesignalLog ( . LL_VERBOSE, message: " OSOperationRepo calling start() " )
6466 // register as user observer
6567 NotificationCenter . default. addObserver ( self ,
66- selector: #selector( self . flushDeltaQueue ) ,
68+ selector: #selector( self . addFlushDeltaQueueToDispatchQueue ) ,
6769 name: Notification . Name ( OS_ON_USER_WILL_CHANGE) ,
6870 object: nil )
6971 // Read the Deltas from cache, if any...
@@ -77,7 +79,7 @@ public class OSOperationRepo: NSObject {
7779 }
7880
7981 private func pollFlushQueue( ) {
80- DispatchQueue . global ( ) . asyncAfter ( deadline: . now( ) + . milliseconds( pollIntervalMilliseconds) ) { [ weak self] in
82+ self . dispatchQueue . asyncAfter ( deadline: . now( ) + . milliseconds( pollIntervalMilliseconds) ) { [ weak self] in
8183 self ? . flushDeltaQueue ( )
8284 self ? . pollFlushQueue ( )
8385 }
@@ -102,16 +104,21 @@ public class OSOperationRepo: NSObject {
102104 return
103105 }
104106 start ( )
105- OneSignalLog . onesignalLog ( . LL_VERBOSE, message: " OSOperationRepo enqueueDelta: \( delta) " )
106-
107- deltaQueueLock. locked {
108- deltaQueue. append ( delta)
107+ self . dispatchQueue. async {
108+ OneSignalLog . onesignalLog ( . LL_VERBOSE, message: " OSOperationRepo enqueueDelta: \( delta) " )
109+ self . deltaQueue. append ( delta)
109110 // Persist the deltas (including new delta) to storage
110111 OneSignalUserDefaults . initShared ( ) . saveCodeableData ( forKey: OS_OPERATION_REPO_DELTA_QUEUE_KEY, withValue: self . deltaQueue)
111112 }
112113 }
113114
114- @objc public func flushDeltaQueue( inBackground: Bool = false ) {
115+ @objc public func addFlushDeltaQueueToDispatchQueue( inBackground: Bool = false ) {
116+ self . dispatchQueue. async {
117+ self . flushDeltaQueue ( inBackground: inBackground)
118+ }
119+ }
120+
121+ private func flushDeltaQueue( inBackground: Bool = false ) {
115122 guard !paused else {
116123 OneSignalLog . onesignalLog ( . LL_DEBUG, message: " OSOperationRepo not flushing queue due to being paused " )
117124 return
@@ -125,38 +132,36 @@ public class OSOperationRepo: NSObject {
125132 OSBackgroundTaskManager . beginBackgroundTask ( OPERATION_REPO_BACKGROUND_TASK)
126133 }
127134
128- start ( )
135+ self . start ( )
129136
130- deltaQueueLock. locked {
131- if !deltaQueue. isEmpty {
132- OneSignalLog . onesignalLog ( . LL_VERBOSE, message: " OSOperationRepo flushDeltaQueue in background: \( inBackground) with queue: \( deltaQueue) " )
133- }
137+ if !self . deltaQueue. isEmpty {
138+ OneSignalLog . onesignalLog ( . LL_VERBOSE, message: " OSOperationRepo flushDeltaQueue in background: \( inBackground) with queue: \( self . deltaQueue) " )
139+ }
134140
135- var index = 0
136- for delta in deltaQueue {
137- if let executor = deltasToExecutorMap [ delta. name] {
138- executor. enqueueDelta ( delta)
139- deltaQueue. remove ( at: index)
140- } else {
141- // keep in queue if no executor matches, we may not have the executor available yet
142- index += 1
143- }
141+ var index = 0
142+ for delta in self . deltaQueue {
143+ if let executor = self . deltasToExecutorMap [ delta. name] {
144+ executor. enqueueDelta ( delta)
145+ self . deltaQueue. remove ( at: index)
146+ } else {
147+ // keep in queue if no executor matches, we may not have the executor available yet
148+ index += 1
144149 }
150+ }
145151
146- // Persist the deltas (including removed deltas) to storage after they are divvy'd up to executors.
147- OneSignalUserDefaults . initShared ( ) . saveCodeableData ( forKey: OS_OPERATION_REPO_DELTA_QUEUE_KEY, withValue: self . deltaQueue)
152+ // Persist the deltas (including removed deltas) to storage after they are divvy'd up to executors.
153+ OneSignalUserDefaults . initShared ( ) . saveCodeableData ( forKey: OS_OPERATION_REPO_DELTA_QUEUE_KEY, withValue: self . deltaQueue)
148154
149- for executor in executors {
150- executor. cacheDeltaQueue ( )
151- }
155+ for executor in self . executors {
156+ executor. cacheDeltaQueue ( )
157+ }
152158
153- for executor in executors {
154- executor. processDeltaQueue ( inBackground: inBackground)
155- }
159+ for executor in self . executors {
160+ executor. processDeltaQueue ( inBackground: inBackground)
161+ }
156162
157- if inBackground {
158- OSBackgroundTaskManager . endBackgroundTask ( OPERATION_REPO_BACKGROUND_TASK)
159- }
163+ if inBackground {
164+ OSBackgroundTaskManager . endBackgroundTask ( OPERATION_REPO_BACKGROUND_TASK)
160165 }
161166 }
162167}
0 commit comments