@@ -36,10 +36,13 @@ public class OSOperationRepo: NSObject {
3636 public static let sharedInstance = OSOperationRepo ( )
3737 private var hasCalledStart = false
3838
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( ) )
41+
3942 // Maps delta names to the interfaces for the operation executors
4043 var deltasToExecutorMap : [ String : OSOperationExecutor ] = [ : ]
4144 var executors : [ OSOperationExecutor ] = [ ]
42- var deltaQueue : [ OSDelta ] = [ ]
45+ private var deltaQueue : [ OSDelta ] = [ ]
4346
4447 // TODO: This could come from a config, plist, method, remote params
4548 var pollIntervalMilliseconds = Int ( POLL_INTERVAL_MS)
@@ -62,7 +65,7 @@ public class OSOperationRepo: NSObject {
6265 OneSignalLog . onesignalLog ( . LL_VERBOSE, message: " OSOperationRepo calling start() " )
6366 // register as user observer
6467 NotificationCenter . default. addObserver ( self ,
65- selector: #selector( self . flushDeltaQueue ) ,
68+ selector: #selector( self . addFlushDeltaQueueToDispatchQueue ) ,
6669 name: Notification . Name ( OS_ON_USER_WILL_CHANGE) ,
6770 object: nil )
6871 // Read the Deltas from cache, if any...
@@ -76,7 +79,7 @@ public class OSOperationRepo: NSObject {
7679 }
7780
7881 private func pollFlushQueue( ) {
79- DispatchQueue . global ( ) . asyncAfter ( deadline: . now( ) + . milliseconds( pollIntervalMilliseconds) ) { [ weak self] in
82+ self . dispatchQueue . asyncAfter ( deadline: . now( ) + . milliseconds( pollIntervalMilliseconds) ) { [ weak self] in
8083 self ? . flushDeltaQueue ( )
8184 self ? . pollFlushQueue ( )
8285 }
@@ -101,14 +104,21 @@ public class OSOperationRepo: NSObject {
101104 return
102105 }
103106 start ( )
104- OneSignalLog . onesignalLog ( . LL_VERBOSE, message: " OSOperationRepo enqueueDelta: \( delta) " )
105- deltaQueue. append ( delta)
107+ self . dispatchQueue. async {
108+ OneSignalLog . onesignalLog ( . LL_VERBOSE, message: " OSOperationRepo enqueueDelta: \( delta) " )
109+ self . deltaQueue. append ( delta)
110+ // Persist the deltas (including new delta) to storage
111+ OneSignalUserDefaults . initShared ( ) . saveCodeableData ( forKey: OS_OPERATION_REPO_DELTA_QUEUE_KEY, withValue: self . deltaQueue)
112+ }
113+ }
106114
107- // Persist the deltas (including new delta) to storage
108- OneSignalUserDefaults . initShared ( ) . saveCodeableData ( forKey: OS_OPERATION_REPO_DELTA_QUEUE_KEY, withValue: self . deltaQueue)
115+ @objc public func addFlushDeltaQueueToDispatchQueue( inBackground: Bool = false ) {
116+ self . dispatchQueue. async {
117+ self . flushDeltaQueue ( inBackground: inBackground)
118+ }
109119 }
110120
111- @ objc public func flushDeltaQueue( inBackground: Bool = false ) {
121+ private func flushDeltaQueue( inBackground: Bool = false ) {
112122 guard !paused else {
113123 OneSignalLog . onesignalLog ( . LL_DEBUG, message: " OSOperationRepo not flushing queue due to being paused " )
114124 return
@@ -122,16 +132,17 @@ public class OSOperationRepo: NSObject {
122132 OSBackgroundTaskManager . beginBackgroundTask ( OPERATION_REPO_BACKGROUND_TASK)
123133 }
124134
125- start ( )
126- if !deltaQueue. isEmpty {
127- OneSignalLog . onesignalLog ( . LL_VERBOSE, message: " OSOperationRepo flushDeltaQueue in background: \( inBackground) with queue: \( deltaQueue) " )
135+ self . start ( )
136+
137+ if !self . deltaQueue. isEmpty {
138+ OneSignalLog . onesignalLog ( . LL_VERBOSE, message: " OSOperationRepo flushDeltaQueue in background: \( inBackground) with queue: \( self . deltaQueue) " )
128139 }
129140
130141 var index = 0
131- for delta in deltaQueue {
132- if let executor = deltasToExecutorMap [ delta. name] {
142+ for delta in self . deltaQueue {
143+ if let executor = self . deltasToExecutorMap [ delta. name] {
133144 executor. enqueueDelta ( delta)
134- deltaQueue. remove ( at: index)
145+ self . deltaQueue. remove ( at: index)
135146 } else {
136147 // keep in queue if no executor matches, we may not have the executor available yet
137148 index += 1
@@ -141,17 +152,16 @@ public class OSOperationRepo: NSObject {
141152 // Persist the deltas (including removed deltas) to storage after they are divvy'd up to executors.
142153 OneSignalUserDefaults . initShared ( ) . saveCodeableData ( forKey: OS_OPERATION_REPO_DELTA_QUEUE_KEY, withValue: self . deltaQueue)
143154
144- for executor in executors {
155+ for executor in self . executors {
145156 executor. cacheDeltaQueue ( )
146157 }
147158
148- for executor in executors {
159+ for executor in self . executors {
149160 executor. processDeltaQueue ( inBackground: inBackground)
150161 }
151162
152163 if inBackground {
153164 OSBackgroundTaskManager . endBackgroundTask ( OPERATION_REPO_BACKGROUND_TASK)
154165 }
155-
156166 }
157167}
0 commit comments