Created
October 16, 2013 20:26
-
-
Save ZackMcBride/7014220 to your computer and use it in GitHub Desktop.
Asynchronous, scheduled outbox thread. This snippet was used for a bespoke project where they required phones to be syncing up constantly with their API. This allows for all requests to be queued on the device and synced up at a later date when there is connectivity.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This method acts as an entry point for the outbox service thread, it will create an additional thread in a continuous loop for the outbox services | |
- (void)startAndObserveOutboxThread { | |
// Only carry out the rest of the method if this isn't the main thread and there isn't a locationServiceObserverThread already running | |
if ([NSThread isMainThread] || outboxServiceObserverThread != nil) { | |
return; | |
} | |
outboxServiceObserverThread = [NSThread currentThread]; | |
// 'Get permission' to run in the background indefinitely by passing expiration handler that 'ends' and restarts background task | |
// iOS calls this when our background time is up, we have to play nice and end the thread, before creating another | |
dispatch_block_t __block expirationHandler = ^{ | |
if ([outboxServiceObserverThread isExecuting]) { | |
// Inform observer thread that it is time to cancel | |
[outboxServiceObserverThread cancel]; | |
// Wait for thread to finish | |
while (![outboxServiceObserverThread isCancelled]) { | |
[NSThread sleepForTimeInterval: 0.1]; | |
} | |
// Start it again | |
[self performSelectorInBackground:@selector(startAndObserveOutboxThread) withObject:nil]; | |
} | |
}; | |
outboxServiceIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler: expirationHandler]; | |
// Run loop while observer thread hasn't been cancelled | |
while(![outboxServiceObserverThread isCancelled]) { | |
// If we don't have an active service work thread, create one | |
if (outboxServiceWorkThread == nil || [outboxServiceWorkThread isFinished] || [outboxServiceWorkThread isCancelled]) { | |
NSLog(@"outboxServiceObserverThread: Starting work thread."); | |
outboxServiceWorkThread = [[NSThread alloc] initWithTarget:[WpDatabase sharedDatabase] selector:@selector(schedule) object:nil]; | |
[outboxServiceWorkThread start]; | |
} else { | |
NSLog(@"outboxServiceObserverThread: Work thread is still running."); | |
} | |
// Sleep observer thread for 60 seconds, so we aren't over checking | |
[NSThread sleepForTimeInterval: 15]; | |
NSLog(@"outboxServiceObserverThread: Checking work thread's state."); | |
} | |
// Mark thread as finished | |
[[UIApplication sharedApplication] endBackgroundTask: outboxServiceIdentifier]; | |
// Set thread ref to nil | |
outboxServiceObserverThread = nil; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment