我怎么知道什么时候可以安全地重用来自另一个进程的后台 NSURLSessionConfiguration id?

How can I know when it's safe to reuse a background NSURLSessionConfiguration id from another process?

我正在构建一个应用程序,用户可以在其中启动从应用程序和共享扩展程序上传后台文件。用户应该能够从主应用程序监控任何上传的进度。

在从扩展启动上传的情况下,我需要创建一个后台会话配置,其 ID 与扩展中使用的 ID 相同,以获取委托调用以监控应用程序中的进度等。

在扩展程序退出之前,我无法在应用程序中执行此操作。 苹果文档说 https://developer.apple.com/library/prerelease/content/documentation/Cocoa/Conceptual/URLLoadingSystem/Articles/UsingNSURLSession.html

You must create exactly one session per identifier (specified when you create the configuration object). The behavior of multiple sessions sharing the same identifier is undefined.

我已经验证过了。如果我不关闭共享扩展,我可以在主应用程序中创建会话而不会出现任何错误,但我不会收到任何委托调用。 当我在切换回主应用程序之前关闭扩展程序时,我可以附加到相同的后台会话并收到委托呼叫。一切顺利。

当我在 NSExtensionContext 中使用 completeRequestReturningItems:completionHandler: 关闭共享扩展时,进程何时退出?

https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSExtensionContext_Class/#//apple_ref/occ/instm/NSExtensionContext/completeRequestReturningItems:completionHandler:

提到

Calling this method eventually dismisses the app extension’s view controller.

"Eventually"不是很具体。我如何从主应用程序中确定扩展程序不是 运行?

我想出的唯一解决方法是定期在共享容器中写入一个文件,并让主 upp 在超过该时间段的超时后首先获取后台会话。但这是一个丑陋的 hack。

如果上传较小,是否有可能在扩展过程中完成上传 运行 以便我必须在扩展而不是主应用程序中处理上传完成?

总结一下:如何安全地将上传内容从应用程序扩展程序传输到应用程序?

Quinn "the Eskimo!" on the old Dev Forums here.

对这个 class 问题进行了一些很好的讨论

与您直接相关的部分是

In my tests I've noticed that some annoying behaviour falls out of this design: if you start a task from an extension, it's non-deterministic as to whether the app or extension gets the didCompleteWithError callback. If the task runs super quickly, the extension typically gets the callback. If the task takes longer, the system has time to terminate the extension and the app is resumed to handle it.

There's really no way around this. The workaround is to put the code that handles request completion in both your app and your extension (possibly reusing the code via a framework).

It would be nice if the extension could disconnect from the session immediately upon starting its request. Alas, that's not currently possible (rdar://problem/18748008). The only way to programmatically disconnect from the session is to invalidate it, and that either cancels all the running tasks (-invalidateAndCancel) or waits for them to complete (-finishTasksAndInvalidate), neither of which is appropriate.

太棒了,

is it possible that the upload finishes while the extension process is running so that I must handle the completion of the upload in the extension

是的。是的。你不喜欢 "non-deterministic" 行为吗?

how do you safely transfer an upload from an app extension to an app?

当然听起来你做不到。所以在那里欺骗雷达,然后耐心等待修复!