iOS 后台获取自定义间隔

iOS background fetch custom interval

我阅读了所有关于后台获取的 Apple 文档,目前我是这样使用它的:

[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:minimumBackgroundFetchInterval];

我让OS决定何时执行后台获取,但如果我这样设置:

[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:21600];

这是否意味着每 6 小时提取一次?

不,这意味着您建议 iOS 在执行后台提取之前至少应经过六个小时,但此 属性 的文档指出 -

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.

因此,执行后台提取可能需要六个多小时,但可能不会更少。 iOS 还会通过完成处理程序记录您 return 的值,指示是否有新数据,以尝试确定您的应用程序可能有新数据的一天中的时间。

我在iOS10和iPhone6Plus上做了一些实验,给了"UIApplicationBackgroundFetchIntervalMinimum"区间。 (当然,我调用了一些与网络相关的方法来提示 iOS 应用程序确实在工作......并调用 completionHandler(UIBackgroundFetchResultNewData); )

我得到了:(运行 整晚)

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

所以 Delta 从 10 到 34 分钟不等。

请求的代码广告:

- (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;
}

回调:

-(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);

}

其他方法:

-(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;
    }

我确实使用了服务器,因为我的设备可能处于休眠状态,我想在我的 mac 上回复邮件。

PHP 服务器上的代码简单地解析 GET 并向我发送一封带有设备 ID 的邮件,这样我就可以在我的 mac.

上解析结果