我如何知道何时可以安全地重用来自另一个进程的后台 NSURLSessionConfiguration id?
Posted
技术标签:
【中文标题】我如何知道何时可以安全地重用来自另一个进程的后台 NSURLSessionConfiguration id?【英文标题】:How can I know when it's safe to reuse a background NSURLSessionConfiguration id from another process? 【发布时间】:2016-06-30 08:02:27 【问题描述】:我正在构建一个应用程序,用户可以在其中启动应用程序和共享扩展的后台文件上传。用户应该能够监控从主应用上传的任何进度。
在从扩展程序启动上传的情况下,我需要创建一个后台会话配置,其 ID 与扩展程序中使用的相同,以获取委托调用以监控应用程序中的进度等。
在应用程序中,我无法在扩展程序退出之前执行此操作。 苹果文档说https://developer.apple.com/library/prerelease/content/documentation/Cocoa/Conceptual/URLLoadingSystem/Articles/UsingNSURLSession.html
您必须为每个标识符创建一个会话(当您指定 创建配置对象)。多个会话的行为 共享相同的标识符是未定义的。
我已经验证了这一点。如果我不关闭共享扩展,我可以在主应用程序中创建会话而不会出现任何错误,但我不会收到任何委托呼叫。 当我在切换回主应用程序之前关闭扩展程序时,我可以附加到同一个后台会话并收到委托呼叫。都很好。
当我在NSExtensionContext
中使用completeRequestReturningItems:completionHandler:
关闭共享扩展时,进程何时退出?
https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSExtensionContext_Class/#//apple_ref/occ/instm/NSExtensionContext/completeRequestReturningItems:completionHandler:
提及
调用此方法最终会关闭应用扩展的视图 控制器。
“最终”不是很具体。我如何从主应用中确定扩展程序没有运行?
我想出的唯一解决方法是定期在共享容器中写入一个文件,并让主 upp 在超时时间超过该时间段后首先获取后台会话。但这是一个丑陋的 hack。
如果上传量很小,是否有可能在扩展程序运行时完成上传,所以我必须在扩展程序中而不是在主应用程序中处理上传的完成?
总结一下:如何安全地将上传内容从应用扩展传输到应用?
【问题讨论】:
【参考方案1】:Quinn“爱斯基摩人!”对这类问题进行了精彩的讨论。 on the old Dev Forums here.
与你直接相关的部分是
在我的测试中,我注意到这种设计中出现了一些烦人的行为:如果您从扩展程序启动任务,则应用程序或扩展程序是否获得 didCompleteWithError 回调是不确定的。如果任务运行得非常快,扩展通常会收到回调。如果任务花费的时间更长,系统有时间终止扩展,并恢复应用程序来处理它。
真的没有办法解决这个问题。解决方法是将处理请求完成的代码放在您的应用和扩展程序中(可能通过框架重用代码)。
如果扩展程序可以在开始请求时立即断开会话,那就太好了。唉,这目前是不可能的(rdar://problem/18748008)。以编程方式断开会话的唯一方法是使其无效,并且取消所有正在运行的任务 (-invalidateAndCancel) 或等待它们完成 (-finishTasksAndInvalidate),这两种方法都不合适。
太好了,
是否有可能在扩展进程运行时上传完成,所以我必须在扩展中处理上传的完成
是的。是的。你不喜欢“不确定”的行为吗?
如何安全地将上传内容从应用扩展传输到应用?
当然听起来你不能。所以在那里欺骗雷达,然后耐心等待修复!
【讨论】:
这似乎(不幸的是:))是正确的答案。我必须实现通过共享容器中的文件的消息传递和心跳机制,我每秒左右更新一个文件,以了解何时可以安全地移交会话。以上是关于我如何知道何时可以安全地重用来自另一个进程的后台 NSURLSessionConfiguration id?的主要内容,如果未能解决你的问题,请参考以下文章