使用begin​Background​Task​With​Expiration​Handler​进行上传

Posted

技术标签:

【中文标题】使用begin​Background​Task​With​Expiration​Handler​进行上传【英文标题】:using begin​Background​Task​With​Expiration​Handler​ for upload 【发布时间】:2017-03-31 20:15:26 【问题描述】:

从doc 看来,上传文件是使用begin​Background​Task​With​Expiration​Handler​ 的一个很好的用例。我发现使用

let uploadTask = session.uploadTask(with: request as URLRequest, fromFile: file)
uploadTask.resume()

将在应用程序后台运行时运行(我正在收到上传进度 ping 一段时间)。此外,我可以将 URLSession 设置为后台:

let config = URLSessionConfiguration.background(withIdentifier: "uploads")
session = URLSession(configuration: config, delegate: self, delegateQueue: nil)

那么使用begin​Background​Task​With​Expiration​Handler 有什么好处呢?它会延长我完成上传的时间吗?如果是这样,我能知道多少(在文档中没有看到任何关于此的内容)?还是只是在应用停止之前我会被 ping 通?我应该将它与背景 URLSession 结合使用吗?

此外,文档说处理程序将在应用程序的剩余后台时间达到 0 之前不久被调用这是否意味着应用程序将在此之后终止?即我可以假设下一个电话将是application:didFinishLaunchingWithOptions 还是applicationDidBecomeActive

【问题讨论】:

另外,请注意,您在 Xcode 下运行时看到的后台执行与“正常”执行时看到的不同。在 Xcode 下,您可以获得无限的后台时间。 啊,太好了。 @Paulw11 当您说“在 Xcode 下”时,是指从 Xcode 在我的设备上运行还是仅在模拟器中运行?我在后台 URLSession 上添加了信息,因为我想知道是否应该将其与 begin​Background​Task​With​Expiration​Handler 结合使用,或者后台 URLSession 是否足够智能以处理所有后台事件 如果您从 Xcode 开始运行,则在模拟器和您的设备上。如果您在后台运行足够长的时间,您将看到 bakckgroundTimeRemaining 达到 0,但您的应用程序仍在继续。通常你的应用会在那个时候被杀死。 【参考方案1】:

此后台任务将让您的应用在用户离开您的应用 3 分钟左右后继续在后台运行(查看background​Time​Remaining 的实际值)以完成您的请求。而且,是的,在这 3 分钟快结束时,如果您还没有结束后台任务,将调用超时处理程序。

因此,如果您在应用程序正常运行期间结束后台任务,则不需要调用此超时关闭。此关闭仅用于任何快速的最后一分钟清理,您可能需要在应用程序停止在后台运行之前执行此操作,因为它在您有机会指示后台任务结束之前超时。这不是为了开始任何新事物,而是为了最后一秒的清理工作。并确保在此超时处理程序中结束后台任务......如果您不结束后台任务,操作系统将立即终止您的应用程序,而不仅仅是暂停它。通常,在此超时关闭中您唯一需要做的就是结束后台任务,但如果您需要进行任何其他清理,这就是您可以做到的地方。

不用说,您必须结束您的后台任务(在网络请求完成时,或者在超时处理程序中,如果您的应用还没有机会在其正常流量)。如果你不这样做,你的应用程序不仅会被暂停,而且会被杀死。

关于假设用户稍后重新启动您的应用时会发生什么,您无法假设将调用哪个应用委托方法。即使你优雅地结束了后台任务,你也不能保证它不会因为其他原因(例如内存压力)而被抛弃。所以不要假设任何事情。

【讨论】:

谢谢。您是否对@Matt 的回答有意见,该回答表明使用URLSessionConfiguration.background 更好,并且完全取代了对begin​Background​Task​With​Expiration​Handler 的需求,因为它“即使在应用程序本身被暂停或终止时也可以继续传输。” developer.apple.com/reference/foundation/… 后台会话非常适合上传/下载许多大型资产,或者在您发送请求时用户可能处于离线状态。但它比标准的URLSession API 复杂得多,所以你必须权衡利弊。有些情况需要背景URLSession。有时你只需要这个简单的后台任务 API。 仅供参考,如果您使用的是后台URLSession,那么这个后台任务是完全没有必要的。您通常使用其中一种。 我明白了。你能详细说明为什么它很多更复杂吗?从我所见,我必须处理 application:​handle​Events​For​Background​URLSession:​completion​Handler:​ 并在完成后调用完成处理程序,但在文档和在线示例中我没有看到任何更复杂的内容。 不能使用数据任务,只能上传和下载任务。此外,您不能使用方便的基于完成处理程序的 API,而必须实现基于委托的 API。此外,如果进行上传,则不能进行数据或流上传,而只能进行基于文件的上传。您可能会检查性能,因为后台请求可能会慢一点。此外,调试有点复杂。这些都不是火箭科学,但它比带有完成处理程序的简单默认 URLSession 更复杂。【参考方案2】:

那么使用begin​Background​Task​With​Expiration​Handler有什么好处呢?

如果你打算使用URLSessionConfiguration.background,没有这样的优势,你根本不应该使用beginBackgroundTask(expirationHandler:)。你的整个前提(你的第一句话)是错误的。上传文件不是beginBackgroundTask(expirationHandler:) 的好用例。这是URLSessionConfiguration.background 的一个很好的用例。这两件事没有任何关系。

【讨论】:

啊!并且文档说“例如,您的应用程序可以调用此方法以确保有足够的时间将重要文件传输到远程服务器”... @Guig 如果您已经在做某事(某事 short)并且您担心用户可能会在后台处理您的应用并因此中断它,您可以要求当我们进入后台时,简要延长运行时间,只是为了完成那件事。上传不太适合(可能根本不短)。这与进行background URL 会话的概念正交;后者让系统在任何认为合适的时候代表您进行长时间的网络活动。

以上是关于使用begin​Background​Task​With​Expiration​Handler​进行上传的主要内容,如果未能解决你的问题,请参考以下文章

当应用程序使用 react-native-background-task 在后台运行时如何调用函数?

background_task.py 不显示消息 - Python

UIApplication Background Task Notes

UWP -- Background Task 深入解析

无法运行 react-native-background-task。将代码插入 MainApplication.java 时出错

除了 react-native-background-task 之外,还有其他方法可以在 React Native 中执行后台任务吗?