ThBM
ThBM

Reputation: 71

Swift 3 - Running a function even when app is in background

I'm facing troubles with my iOS app. I would like to run a function every day even if my application is not on foreground on my IPhone. I tried to use NSTimer Object but it doesn't work if my app is in background.

How can I achieve this?

Note: My function will trigger a notification which differs based on the current day.

Upvotes: 1

Views: 2075

Answers (2)

Poke
Poke

Reputation: 491

Paulw11 is correct. You can use background refresh and a local notification. The background fetch will be called randomly. Each time it is called the local notification will reset. This code is Obj C, it is a bit old, but the concept is the same.

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


BackgroundFetch * fetch = [[BackgroundFetch alloc] init];

[fetch fetchNewDataWithCompletionHandler:^(UIBackgroundFetchResult result) {
    completionHandler(result);
} successDictionary:^(NSDictionary *responseDict) {

  // Schedule local notification, in this case it is 9am

   [[UIApplication sharedApplication] cancelAllLocalNotifications];

        UILocalNotification *notif = [[UILocalNotification alloc] init];

            NSCalendar *calendar = [NSCalendar currentCalendar];
            NSDateComponents *components = [[NSDateComponents alloc] init];

            components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]];

            NSInteger day = [components day];
            NSInteger month = [components month];
            NSInteger year = [components year];

            [components setDay: day];
            [components setMonth: month];
            [components setYear: year];
            [components setHour: 9];
            [components setMinute: 0];
            [components setSecond: 0];
            [calendar setTimeZone: [NSTimeZone systemTimeZone]];
            NSDate *dateToFire = [calendar dateFromComponents:components];

        notif.fireDate = dateToFire;
        notif.timeZone = [NSTimeZone systemTimeZone];
        notif.alertBody = [NSString stringWithFormat:@"%@: %@", responseDict[@"city"], responseDict[@"temp"]];

        [[UIApplication sharedApplication] scheduleLocalNotification:notif];
}

Upvotes: 5

matt
matt

Reputation: 536018

You can't do it, because you can't run in the background, and in fact your app might not even be running. So rethink your architecture. For example, set up 30 notifications for the next 30 days, in case your app never runs during that time. That's what a notification is: a message delivered on your behalf by the system, which is always running.

Upvotes: 0

Related Questions