iOS:在应用程序处于后台时执行上传任务

Posted

技术标签:

【中文标题】iOS:在应用程序处于后台时执行上传任务【英文标题】:iOS: Perform upload task while app is in background 【发布时间】:2014-07-12 19:58:12 【问题描述】:

真的没有办法在 ios 应用程序在后台运行 UPLOAD 任务吗?这是荒唐的。一直在查看NSURLSessionUploadTaskdispatch_after 甚至NSTimer 之类的各种内容,但应用程序在被置于后台后的短短 10 秒内没有任何效果。

其他具有上传功能的应用如何工作?比如说,将图片上传到 Facebook 并将应用置于后台,这会取消上传吗?

为什么 iOS 不能像 android 和 Windows Phone 那样拥有后台服务或代理?

这是我的应用程序的一个关键功能,在其他平台上也可以完美运行。

任何帮助表示赞赏:(

【问题讨论】:

如果您能够创建和调用 Web 服务为您执行任务,这似乎可以使用服务器端编程。检查链接:***.com/questions/25725811/…。不确定,如果它与你相关。 【参考方案1】:

您可以通过“后台会话”在后台继续上传。在Downloading Files in the Background 中概述了使用background(withIdentifier:) 创建背景URLSessionConfiguration 的基本过程。该文档侧重于下载,但同样的基本流程也适用于上传任务。

注意:

你必须使用基于委托的URLSession

您不能将任务工厂方法的完成处理程序再现与后台会话一起使用;

您还必须使用uploadTask(with:fromFile:) 方法,而不是Data 再现...如果您尝试使用uploadTask(with:from:),它使用Data 作为有效负载,背景为URLSession,您将收到异常一条消息,“后台会话不支持从 NSData 上传任务”;和

您的应用委托必须实现 application(_:handleEventsForBackgroundURLSession:completionHandler:) 并捕获完成处理程序,然后您可以在您的 URLSessionDelegate 方法 urlSessionDidFinishEvents(forBackgroundURLSession:) 中调用它(或在您完成处理响应时调用)。


顺便说一句,如果你不想使用后台NSURLSession,但你想在应用离开后台后继续运行有限长度的任务超过几秒钟,你可以使用@请求更多时间987654340@ 方法beginBackgroundTask。即使用户离开应用程序,这也会给您一点时间(以前为 3 分钟,在 iOS 13 及更高版本中仅为 30 秒)完成您正在处理的任何任务。

见Extending Your App's Background Execution Time。他们的代码 sn-p 有点过时了,但现代版本可能看起来像:

func initiateBackgroundRequest(with data: Data) 
    var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid

    // Request the task assertion and save the ID.
    backgroundTaskID = UIApplication.shared.beginBackgroundTask(withName: "Finish Network Tasks") 
        // End the task if time expires.
        if backgroundTaskID != .invalid 
            UIApplication.shared.endBackgroundTask(backgroundTaskID)
            backgroundTaskID = .invalid
        
    

    // Send the data asynchronously.
    performNetworkRequest(with: data)  result in
        // End the task assertion.
        if backgroundTaskID != .invalid 
            UIApplication.shared.endBackgroundTask(backgroundTaskID)
            backgroundTaskID = .invalid
        
    

请不要迷失在此处的详细信息中。关注基本模式:

开始后台任务; 提供一个超时子句,在你碰巧用完时间时清理后台任务; 即使用户离开应用程序,也可以启动您需要继续的任何操作;和 在网络请求的完成处理程序中,结束后台任务。

【讨论】:

你确定completionHandler?我在uploadTaskWithRequest:fromFile:completionHandler: 方法文档中没有发现任何提及它不能用于后台上传任务。 查看documentation for URLSession,上面写着“因为您的应用可能会在传输过程中退出并重新启动,所以不支持完成处理程序块。” 参考background类方法的注释,它们是否仍然适用或有任何更新? @hannojg - 曾经在他们的旧“URL 编程指南”中进行了概述,随后他们用新的文档替换了该文档,该文档未能清楚地概述后台上传要求。描述这一点的 2015 年之前的原始视频似乎也消失了。但是,只需在后台会话中尝试uploadTask(with:from:),您将收到一个明确的异常报告,“后台会话不支持从 NSData 上传任务”。这证实了这些对后台上传的限制仍然适用。 FWIW,这个“不支持 NSData”用于后台上传是一个完全可以理解的限制,恕我直言。他们真的不想让他们的后台守护进程不得不在内存中保留巨大的Data/NSData 对象。如果资源太大以至于您需要后台上传(而不是在用户离开应用程序后仅请求额外的 30 秒来完成标准 URLSession),那么无论如何,基于文件的上传将是首选(即使对于非-背景URLSession)。

以上是关于iOS:在应用程序处于后台时执行上传任务的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 应用程序处于后台时上传视频文件?

ios - 在后台创建会话下载任务

Xamarin.Forms iOS - 当设备连接互联网时开始上传数据,即使应用程序当前未处于活动状态或处于后台也是如此

上传大型视频iOS时延长后台任务超时时间[关闭]

应用程序处于后台时的 iOS 可达性

如何在应用程序处于后台时执行 Core Data 操作