iOS background fetch custom interval
Asked Answered
N

3

9

I read all Apple documentation about background fetch and currently I'm using it like this:

[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:minimumBackgroundFetchInterval];

I let OS to decide when to perform background fetch, but if I set it like this:

[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:21600];

Does that mean that fetch will happen every 6h?

Nonresident answered 7/2, 2015 at 10:34 Comment(1)
What you want is not achievable without Push notifications. Try silent notification, allowing the app to wake up in the background and perform a task.Nagy
C
5

No, it means that you are suggesting to iOS that at least six hours should elapse before a background fetch is performed, but the documentation for this property states -

The minimum number of seconds that must elapse before another background fetch can be initiated. This value is advisory only and does not indicate the exact amount of time expected between fetch operations.

So, it could be more than six hours before a background fetch is performed but probably won't be any less. iOS also takes note of the value you return via the completion handler indicating whether there was new data or not to try and determine the times of the day when there is likely to be new data for your app.

Conspicuous answered 7/2, 2015 at 10:40 Comment(2)
What is the minimum time allowed for background fetch, somewhere I read that it's 30 seconds. Does it means "I can't configure background fetch with an iteration less than 30 sec" ( I want to call an api in an interval of 5 second).Color
No, you have about 30 seconds to execute in the background. The interval would be around 20-30 minutes on average. It depends on network activity, battery state, time of day, charger connected etc.Conspicuous
P
18

I did some experiment on iOS10 and iPhone6Plus, giving "UIApplicationBackgroundFetchIntervalMinimum" interval. (of course I invoked some network-related method to give iOS a hint that app is really working... and invoking completionHandler(UIBackgroundFetchResultNewData); )

I got: (run all night)

00:35 01:03 01:31 01:59 02:27 02:55 03:13 03:23 03:51 04:19 04:35 05:04 05:25 05:59 06:27 06:56

so Delta varies from 10 to 34 mins.

Pate answered 18/7, 2016 at 5:25 Comment(2)
Can you post the code you write to achieve this? In my testings, during the first hour i have frequency rates similar as yours, but past the hour, i don't receive more calls until three or four hours.Cropdusting
Have you tried to invoke without network related stuff?Warmongering
P
6

Code ad requested:

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

    // You must invoke setMinimumBackgroundFetchInterval:.
    [application setMinimumBackgroundFetchInterval: UIApplicationBackgroundFetchIntervalMinimum];

// default, iOS decides. seems between 5 and 15 minutes.
// you cannot go below that time.


    /* ADC:
    (You can also enable this support by including the UIBackgroundModes key with the fetch value in your app’s Info.plist file.) Enabling this mode is not a guarantee that the system will give your app any time to perform background fetches. The system must balance your app’s need to fetch content with the needs of other apps and the system itself. After assessing that information, the system gives time to apps when there are good opportunities to do so.

        When a good opportunity arises, the system WAKES or LAUNCHES your app into the background and calls the app delegate’s application:performFetchWithCompletionHandler: method. Use that method to check for new content and initiate a download operation if content is available.
    */

    // UIApplicationState state = application.applicationState;
    NSString * s = [NSString stringWithFormat:@"background=%d (didFinishLaunchingWithOptions)", application.applicationState == UIApplicationStateBackground];


    return YES;
}

call back:

-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler
{    
    NSInteger n = application.applicationIconBadgeNumber;
    application.applicationIconBadgeNumber = n+1;

    // we invoke an sync method, so we should call handler AFTER getting answer...

    BOOL isIpad = [self isIpad];
    NSString * ID = [[[UIDevice currentDevice] identifierForVendor] UUIDString];

    NSString* msg = [NSString stringWithFormat: @"PFCH=%ld-ipad%d-%@", (long)n, isIpad, ID];
    // call a method on my server to send me back a mail. I add an ID for every device I tested in a battery of iPhone/iPads.
    [self getTime: msg];

    // if ok...
    completionHandler(UIBackgroundFetchResultNewData);

    // or             completionHandler(UIBackgroundFetchResultNoData);
    // or             completionHandler(UIBackgroundFetchResultFailed);

}

other method:

-(void) getTime:(NSString*)msg
{
    NSString* urlS = [NSString stringWithFormat: @"https://www.ingconti.com/PFCH.php?msg=%@", msg];

    NSURL * URL = [NSURL URLWithString: urlS];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];      
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

                                                NSString * s = [[NSString alloc]initWithData:data encoding: NSUTF8StringEncoding];
                                                NSLog(@"%@", s);
                                            }
                                  ];

    [task resume];
}


    -(BOOL)isIpad;
    {
        UIUserInterfaceIdiom deviceType = [[UIDevice currentDevice] userInterfaceIdiom];
        if (deviceType == UIUserInterfaceIdiomPad)
            return YES;

        return NO;
    }

I did use a server as my devices can be dormant, and I want a mail back on my mac.

PHP code on server simply parses GET and send my back a mail with device ID, so I can parse results on my mac.

Pate answered 30/9, 2017 at 6:18 Comment(0)
C
5

No, it means that you are suggesting to iOS that at least six hours should elapse before a background fetch is performed, but the documentation for this property states -

The minimum number of seconds that must elapse before another background fetch can be initiated. This value is advisory only and does not indicate the exact amount of time expected between fetch operations.

So, it could be more than six hours before a background fetch is performed but probably won't be any less. iOS also takes note of the value you return via the completion handler indicating whether there was new data or not to try and determine the times of the day when there is likely to be new data for your app.

Conspicuous answered 7/2, 2015 at 10:40 Comment(2)
What is the minimum time allowed for background fetch, somewhere I read that it's 30 seconds. Does it means "I can't configure background fetch with an iteration less than 30 sec" ( I want to call an api in an interval of 5 second).Color
No, you have about 30 seconds to execute in the background. The interval would be around 20-30 minutes on average. It depends on network activity, battery state, time of day, charger connected etc.Conspicuous

© 2022 - 2024 — McMap. All rights reserved.