Skip to content

Instantly share code, notes, and snippets.

@ZackMcBride
Created October 16, 2013 20:26
Show Gist options
  • Save ZackMcBride/7014220 to your computer and use it in GitHub Desktop.
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 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