In iOS 7 they added the function -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
which allows you to do something in the background when you get a push notification. However they only give you about 30 seconds to do something.
I want to make an NSTimer to let me know if my 30 seconds are almost up, and have it finish what it was doing. It would be nice to pass the completion handler through the timer, so that I can call it when I'm done.
Is there a way to pass the completion handler, (void (^)(UIBackgroundFetchResult))completionHandler
with the NSTimer and call it from the called function?
Yeah, hold the completion handler block in an instance variable:
typedef void(^BackgroundCompletionHandler)(UIBackgroundFetchResult);
@interface YourClass ()
{
BackgroundCompletionHandler _backgroundCompletionHandler;
}
And use a common method to call this stored block:
-(void) application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(BackgroundCompletionHandler)completionHandler
{
_backgroundCompletionHandler = completionHandler;
[NSTimer scheduledTimerWithTimeInterval:30.0
target:self
selector:@selector(timeUp:)
userInfo:nil
repeats:NO];
// Do work
[self callBackgroundCompletionHandler:YES];
}
- (void)timeUp:(NSTimer *)timer
{
[self callBackgroundCompletionHandler:NO];
}
- (void)callBackgroundCompletionHandler:(BOOL)succeeded
{
@synchronized(self)
{
if (_backgrondCompletionHandler) {
_backgroundCompletionHandler(succeeded ? UIBackgroundFetchResultNewData : UIBackgroundFetchResultFailed);
_backgroundCompletionHandler = NULL;
}
}
}