很难找到明确的答案;无法在Apple文档中找到它,并且在搜索过去的问题后无法找到肯定的是/否。
问题很简单 - 如果应用程序请求在N次之后执行后台提取,则用户终止应用程序。操作系统是否仍会将应用程序启动到后台以执行后台提取?
答案 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:您的应用赢了再次被唤醒。
确保您不会杀死该应用(即通过双击该应用 主页按钮并向上滑动您的应用程序以强制应用程序 终止)。如果应用程序被终止,它将阻止后台获取 从正常工作。
它被唤醒真的没有意义......它有点使用户杀死应用程序无效。
有了这个说,有不同的方式可以再次启动终止/强制退出应用程序:
通过使用region monitoring或significant-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.
第二个选项正是下载数据,即使可以终止也可以委托给系统。