1

I'm trying to get my app to perform a background fetch at a specific, scheduled time. I had the idea of letting iOS sort this out for itself, so (in AppDelegate):

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) {
        [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeSound categories:nil]];
    }

    [[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
    return YES;
}

and then (also in AppDelegate)

-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

    NSDate *now = [NSDate date];

    if ((([now timeIntervalSinceDate:lastCheckTime]/60) > 60)||(!lastCheckTime)) { //don't update more than once every hour
        lastCheckTime = now;
        [notificationUpdate getStatusUpdateWithCompletionHandler:completionHandler];
    } else {
        completionHandler(UIBackgroundFetchResultNewData);
    }    
}

If I fire the background check manually, in Xcode, this works perfectly. Sadly, it doesn't work perfectly if I just leave it to its own devices.

How can I schedule a time for my getStatusUpdate function to be executed or cause a background fetch to occur at a specific time (the real life use-case will be that the app will check at around a user defined time, like an alarm clock - this isn't something that will be running all the time and chewing up the battery)

I've found lots on the internet about scheduling an alarm (including here - I found one example here which suggested using CoreLocation to cause the background fetch to fire - I don't know if this would work but, for reasons of power conservation, I don't like the idea.) - but this just causes an alert to be displayed on the screen, and I don't want to display an alert - at least, not before I've checked for status updates.

As always, any help will be very gratefully received (but I fear the answer is that I can't do what I want!).

headbanger
  • 1,038
  • 1
  • 11
  • 32

1 Answers1

2

You cannot do what you want. The only workaround is to implement push notifications and have the API send a push at the designated time.

Aaron Brager
  • 65,323
  • 19
  • 161
  • 287
  • When you say push notifications, you mean from my own server? Or is it possible to set something up so that it runs entirely on the phone? – headbanger Feb 26 '15 at 22:36
  • From your server. You cannot do it entirely on your phone. – Aaron Brager Feb 26 '15 at 23:26
  • What a pity. Here's hoping that Apple permit code to be executed on a schedule next time - it seems like such an obvious thing to do. Obviously, they'll need to ensure that the ability isn't being abused (just as they surely must do for core location geofences) – headbanger Feb 27 '15 at 09:23