I (Basically) need to create a background timer on iOS 4 that will allow me to execute some code when a specific amount of time has passed. I have read that you can accomplish this using some [NSThread detachNewThreadSelector:
toTarget:
withObject:];
but how does that work in practice? How can I ensure that the thread remains in the background also. Local notifications will NOT work for me, as I need to execute code, not notify the user.
Help would be appreciated!
You can use those call to execute a method (selector) of an object (toTarget) with some parameter (withObject) in a new thread (detachNewThred).
Now if you want to execute a delayed task may be the best approach is performSelector: withObject: afterDelay:
and the if you want to run the task on background call the detachNewThreadSelector: toTarget: withObject:
You can also do this using Grand Central Dispatch (GCD). This way you can use blocks to keep your code in one place, and be sure you're calling the main thread again if you need to update your UI after you've finished background processing. Here's a basic example:
#import <dispatch/dispatch.h>
…
NSTimeInterval delay_in_seconds = 3.0;
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, delay_in_seconds * NSEC_PER_SEC);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
UIImageView *imageView = tableViewCell.imageView;
// ensure the app stays awake long enough to complete the task when switching apps
UIBackgroundTaskIdentifier taskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:{}];
dispatch_after(delay, queue, ^{
// perform your background tasks here. It's a block, so variables available in the calling method can be referenced here.
UIImage *image = [self drawComplicatedImage];
// now dispatch a new block on the main thread, to update our UI
dispatch_async(dispatch_get_main_queue(), ^{
imageView.image = image;
[[UIApplication sharedApplication] endBackgroundTask:taskIdentifier];
});
});
Grand Central Dispatch (GCD) reference:
http://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html
Blocks reference:
http://developer.apple.com/library/ios/#featuredarticles/Short_Practical_Guide_Blocks/index.html%23//apple_ref/doc/uid/TP40009758
Background Task reference:
http://developer.apple.com/library/ios/DOCUMENTATION/UIKit/Reference/UIApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/UIApplication/beginBackgroundTaskWithExpirationHandler:
Are these suggested methods only applicable if the application is enabled for background execution (using UIBackgroundMode) in the first place?
I presume if an application cannot legitimately claim to be a voip/music/location aware app then if it implements what is described here it will not execute when the time interval expires?