【问题标题】:iOS 13 background download issueiOS 13 后台下载问题
【发布时间】:2020-05-12 13:10:53
【问题描述】:

我有一个同步功能,可以在后台进行一系列下载。

为此,我创建了一个 URLSession 实例,其背景配置如下:

let config = URLSessionConfiguration.background(withIdentifier: "BackgroundSessionDL")
config.httpMaximumConnectionsPerHost = 20

self.session = URLSession(configuration: config, delegate: self, delegateQueue: nil)

每个下载任务(可能有数百个)添加如下:

var request = URLRequest(url: url)
request.addValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")

let downloadTask = self.session.downloadTask(with: request)
downloadTask.resume()

此代码在 iOS 12 或更早版本上完美运行 - 即使已添加的任务在后台继续下载。 但是,对于 iOS 13,会导致以下问题:

  1. 一旦应用进入后台,下载就会停止。
  2. 如果任何下载任务正在进行并且应用程序被置于后台,即使应用程序再次被置于前台,也不会观察到与回调相关的日志。

我尝试搜索 Apple 是否为 iOS 13 上的后台任务下载引入了任何新的类/框架,但没有找到任何相关内容。此外,早期版本中用于表示后台下载任务的类在 iOS 13 中仍未弃用,并且是在 iOS 13 上搜索后台下载时的唯一结果。同样,用于 HTTP 会话的后台配置仍然不是已弃用。所以,我相信目前的后台下载实现是苹果推荐的。 (据我了解,“BGTaskScheduler”并非为此而生,如有错误请指正)。

那么,这是由于 iOS 13 中新引入的错误造成的吗? 或者,Apple 期望此实现(特定于 iOS 13)有任何变化?

编辑:

我已经添加了handleEventsForBackgroundURLSession 回调。发现在iOS 13的设置中没有打印相应的日志,应用程序大小没有增加。所以,后台下载似乎没有继续,与下载相关的回调没有被调用无关。

【问题讨论】:

  • 你知道如何克服这种行为吗?我有同样的问题,已经花了几天时间试图弄清楚......一切都在 iOS13 上完美运行-

标签: ios swift nsurlsession ios13 nsurlsessiondownloadtask


【解决方案1】:

我猜如果你在前台运行应用程序,那么一切都会按预期运行,但是一旦应用程序进入后台,就不会再收到回调了

BackgroundDownloader 仅在应用处于前台时有效,但在应用进入挂起/后台状态时有特定的支持。

当应用处于挂起/终止状态并且下载完成时,iOS 将通过调用(在后台)唤醒应用:

class AppDelegate: UIResponder, UIApplicationDelegate { 

    func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
        //TODO: Handle processing downloads
    }
}

ios12 和 ios13 之间的行为变化可能与某些 API 变化无关,而只是在应用程序不在前台时采用了更积极的节能策略

修改 URLSession 后台配置标识 将 isDiscretionary 设为 false 以避免操作系统因电池或性能而调度后台请求传输 最重要的应该UseExtendedBackgroundIdleMode 为true。这是使 TCP 套接字即使在应用程序被锁定或挂起时也能打开的终极路线。

【讨论】:

  • 感谢您的回复。你的问题让我意识到这个问题有点模棱两可,所以重新措辞。我已经添加了“handleEventsForBackgroundURLSession”回调,发现没有打印相应的日志。
  • 您能否确认您的所有后台下载都已完成?如果其中一个挂起或失败,它将阻止触发后台会话的完成。委托方法只有在一切都完成后才会被调用,这意味着你的应用程序不会被激活。您是否检查过设备控制台中的一些诊断错误消息?
  • 嗨 cristallo,后台下载未完成(大约有几百个文件,其中至少 2-3 个是并行启动的)。相反,当应用程序进入后台时,我没有看到任何正在进行的下载更新。从设置中的应用程序大小可以看出这一点。我想弄清楚...为什么当应用程序进入后台时下载不会继续。
  • 您是否正确配置了 urlsession 与 shouldUseExtendedBackgroundIdleMode 和自主模式?
  • 是的,我尝试使用 shouldUseExtendedBackgroundIdleMode。此外,尝试使用 isDiscretionary 的 true 和 false 值。然而,它不起作用。我看不到该方法的日志 - func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) 在完成单个任务后调用。
猜你喜欢
  • 1970-01-01
  • 2020-01-25
  • 2020-01-30
  • 2020-01-20
  • 2019-12-12
  • 2011-06-02
  • 1970-01-01
  • 1970-01-01
  • 2020-01-23
相关资源
最近更新 更多