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

时间:2017-06-29 14:42:51

标签: ios background-fetch

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

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

3 个答案:

答案 0 :(得分:5)

好的,再次背景模式会造成混乱。其他人试图提供帮助没有冒犯,但这比看起来更复杂

首先: 正如Sausage在评论中所猜测的那样,This 已经过时了。我知道这是事实,因为有关VoIP应用程序的部分仍在解释执行此操作的“旧方法”,并且会定期调用处理程序。我对this answer进行了一些调查,所以我建议你去看看。这个案例的重要教训是,iOS区分了由用户或系统终止的应用程序,而且无论手机是否重新启动,它都会起作用。

所以总结一下这个(以及你的问题)你基本上想知道上述过时文档的这一部分是否仍然是逐字逐句的:

  

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

     

Apple: Understanding When Your App Gets Launched into the Background

我彻底调查了其余的文档,但没有找到任何明确的答案,所以不幸的是归结为已经建议的:测试它。我的直觉是文档在这方面仍然是正确的(尽管说不是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];
}

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

答案 1 :(得分:2)

根据顶级用户写的这个答案:iOS background fetch:您的应用赢了再次被唤醒。

  

确保您不会杀死该应用(即通过双击该应用   主页按钮并向上滑动您的应用程序以强制应用程序   终止)。如果应用程序被终止,它将阻止后台获取   从正常工作。

它被唤醒真的没有意义......它有点使用户杀死应用程序无效。

有了这个说,有不同的方式可以再次启动终止/强制退出应用程序:

  • 点击通知。
  • 点按应用图标。
  • 使用openUrl从其他应用中打开您的应用。
  • 如果您使用PushKit ...则会启动您的应用。想象一下,如果有一个VOIP应用程序,例如Skype,WhatsApp和一位朋友打电话给你,但你已经强制退出应用程序,你不会接到电话。有关详情,请参阅here
  • 通过使用region monitoringsignificant-change位置服务更新位置信息。请参阅this answer,并确保阅读Apple文档中的this entire page

  • 重新启动设备也会撤消通过强制退出阻止的任何内容

答案 2 :(得分:1)

阅读Apple文档here我找到了这个文本片段,它可以解释你的问题:

  

iOS提供的技术分为三类:

    Apps that start a short task in the foreground can ask for time to finish that task when the app moves to the background.

    **Apps that initiate downloads in the foreground can hand off management of those downloads to the system, thereby allowing the app to be suspended or terminated while the download continues.**

    Apps that need to run in the background to support specific types of tasks can declare their support for one or more background execution modes.

第二个选项正是下载数据,即使可以终止也可以委托给系统。