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

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

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

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

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

所以总结这个(以及你的问题)你基本上想知道上面这部分过时的文档是否仍然是正确的:

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

Apple: 了解您的应用程序何时启动到后台

我彻底调查了其余的文档,但没有找到任何明确的答案,所以不幸的是归结为丹已经建议:测试它。 我的直觉是文档在这方面仍然是正确的(尽管说不是VoIP的东西)。 我之所以这么说,是因为“设置”应用中的用户界面调用了“后台应用刷新”function,因此用户可能应该了解具有此权限的应用在他们将其“推”出背景时不会刷新(即主页按钮 – >把它滑出来)。 对于普通用户,应用要么退出(根本不在任务管理器中),在前台(使用它们)或在后台(它们在任务管理器中,而另一个应用程序在前台和/或手机已锁定) 。


要真正测试这个,你必须编写一个应用程序,并在每种情况下实际携带它(我假设至少两天)。 首先它是在后台(操作系统应该定期让它获取,因为你可能知道这也可以在Xcode中触发)然后在强制退出时。 问题是validation它是否取出了东西。 我会使用可以通过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布尔设置。 我会在我的开发设备上运行一段时间并检查日志文件,最后报告回来。 也可以自己测试一下。

根据这个由顶级用户写的答案: iOS背景提取 :你的应用程序不会再被唤醒。

确保你没有杀死应用程序(即双击主页按钮并向上滑动你的应用程序以强制终止应用程序)。 如果应用程序被终止,将阻止后台获取正常工作。

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

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

  • 点击通知。
  • 点击应用程序图标。
  • 使用openUrl从其他应用程序打开您的应用程序。
  • 如果您使用PushKit …那么您的应用程序将启动。 想象一下,如果有一个VOIP应用程序,例如Skype,WhatsApp和一个朋友打电话给你,但你已经强制退出应用程序,你就不会接到电话。 有关详情,请参阅此处
  • 通过使用区域监控或重要更改位置服务更新位置。 请参阅此答案 ,并确保从Apple文档中阅读整个页面 。

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

在这里阅读Apple文档,我发现这个文本片段可以解释你的问题:

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. 

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