如果应用程序已终止,将调用performFetchWithCompletionHandler

Gru*_*kes 7 ios background-fetch

很难找到明确的答案; 在Apple文档中找不到它,在搜索过去的问题后找不到肯定的是/否.

问题很简单 - 如果应用程序请求在N次之后执行后台提取,则用户终止应用程序.操作系统是否仍会将应用程序启动到后台以执行后台获取?

Ger*_*ero 5

好的,背景模式再次引起混乱。试图帮助其他人没有冒犯,但这比看起来要复杂

首先: 正如香肠在评论中所猜到的, 已经过时了。我之所以知道这一点,是因为有关VoIP应用程序的部分仍在说明使用“处理程序”的“旧方法”,该处理程序会定期调用。我这个考察了一下对于这个答案,所以我建议你去阅读。在此情况下,重要的教训是,iOS区分了由用户或系统终止的应用程序,此外,无论手机是否重启,它也都发挥了作用。

因此,总而言之(基本上是您的问题),您基本上想知道上述过时的文档这部分是否仍然是正确的单词:

在大多数情况下,系统在用户强行退出应用后不会重新启动应用。位置应用程序是一个例外,位置应用程序在iOS 8及更高版本中被用户强行退出后重新启动。但是,在其他情况下,用户必须明确启动应用程序或重新启动设备,然后系统才能将应用程序自动启动到后台。在设备上启用密码保护后,系统不会在用户首次解锁设备之前在后台启动应用程序。

苹果: 了解您的应用何时在后台启动

我彻底研究了其余的文档,但没有找到明确的答案,因此很遗憾地归结为dan已经建议的内容:测试它。我的直觉是,尽管如此,文档在这方面仍然是正确的(正如所说的,不是VoIP的东西)。我说这是因为“设置”应用程序中的用户界面调用了“后台应用程序刷新”功能,因此用户可能应该理解,当具有“权限”的应用程序从后台“推送”时,该应用程序不会刷新(例如,主屏幕按钮- >刷出)。对于普通用户,应用程序要么退出(根本不在任务管理器中),要么在前台(使用它们)退出,要么在后台(它们在任务管理器中,另一个应用程序在前台和/或手机已锁定) 。


要真正测试一下,您必须编写一个应用程序,然后在每种情况下实际进行一些测试(我假设至少需要两天)。首先,在后台运行时(操作系统应该定期让其获取数据,您可能知道这也可以在Xcode中触发),然后在强制退出时运行。问题是验证它是否获取了东西。我会选择一个可以通过iTunes共享的日志文件。我为此输入了一些代码:

-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    NSLog(@"We're awake! Booyah!");

    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config
                                                          delegate:nil
                                                     delegateQueue:[NSOperationQueue mainQueue]];
    NSMutableURLRequest *request = [NSMutableURLRequest new];
    request.HTTPMethod = @"GET";
    request.URL = [NSURL URLWithString:@"https://www.google.com"];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request
                                            completionHandler:^(NSData * _Nullable data,
                                                                NSURLResponse * _Nullable response,
                                                                NSError * _Nullable error) {
                                                NSDate *now = [NSDate date];
                                                NSString *toLog = [NSString stringWithFormat:@"%@ - fetched\n",
                                                                   [now description]];
                                                [self updateTestDocumentWithString:toLog];
                                                NSLog(@"Yay, done!");
                                                completionHandler(UIBackgroundFetchResultNewData);
                                            }];
    [task resume];
}

- (void)updateTestDocumentWithString:(NSString *)toAppend {
    NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSString *filePath = [[docDir stringByAppendingPathComponent:@"logfile.txt"] copy];
    if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
        if (![[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil]) {
            NSLog(@"We're effed...");
            return;
        }
    }
    NSFileHandle *file = [NSFileHandle fileHandleForUpdatingAtPath:filePath];
    if (!file) {
        NSLog(@"We're effed again...");
        return;
    }
    [file seekToEndOfFile];
    // ensure this is never nil
    [file writeData:[toAppend dataUsingEncoding:NSUTF8StringEncoding]];
    [file closeFile];
}
Run Code Online (Sandbox Code Playgroud)

这将进入应用程序委托,并且不要忘记Application supports iTunes file sharing在应用程序的plist中添加布尔值设置。我将其在开发设备上运行一会儿,然后检查日志文件,最后在此处报告。也可以自己进行测试。