不叫我的行动扩展(ActionRequestHandler
)这样开始下载:URLSessionDownloadDelegate didFinishDownloadingTo背景
private lazy var urlSession: URLSession = {
let config = URLSessionConfiguration.background(withIdentifier: "de.stefantrauth.Downloader")
config.sharedContainerIdentifier = "group.de.stefantrauth.Downloader"
return URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main)
}()
private func initiateDownloadOfFileFrom(url: URL) {
urlSession.downloadTask(with: url).resume()
completeRequest() // this tells the system the action extension is done with its work
}
然后在下载iOS版通过在后台处理。
我现在要处理我的主要应用AppDelegate
完成下载,因为这是当下载完成后的iOS所说的。
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping() -> Void) {
print("handleEventsForBackgroundURLSession")
urlSessionBackgroundCompletionHandler = completionHandler
}
如预期的那样在一段时间后调用此方法。
我的AppDelegate
也实现了URLSessionDelegate
和URLSessionDownloadDelegate
来处理下载的更新。
特别有趣的是
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
DispatchQueue.main.async {
print("urlSessionDidFinishEvents")
self.urlSessionBackgroundCompletionHandler?()
self.urlSessionBackgroundCompletionHandler = nil
}
}
和
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
print("download finished to \(location.absoluteString)")
do {
let documentsURL = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let savedURL = documentsURL.appendingPathComponent(location.lastPathComponent)
try FileManager.default.moveItem(at: location, to: savedURL)
print("moved file to: \(savedURL.absoluteString)")
} catch {
print ("file error: \(error)")
}
}
两个urlSessionDidFinishEvents
和didFinishDownloadingTo
不被称为handleEventsForBackgroundURLSession
得到了在后台称为后。只有在将应用程序重新启动到前台后,才能调用委托方法。
为什么他们没有得到所谓的,我能做些什么来解决这个问题?
我试图创造handleEventsForBackgroundURLSession
的URLSession
这样的:
private func initUrlSessionWith(identifier: String) {
let config = URLSessionConfiguration.background(withIdentifier: identifier)
config.sharedContainerIdentifier = "group.de.stefantrauth.Downloader"
urlSession = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main)
}
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping() -> Void) {
print("handleEventsForBackgroundURLSession")
initUrlSessionWith(identifier: identifier)
urlSessionBackgroundCompletionHandler = completionHandler
}
但是这并没有解决问题。
之前你问:是的,我是一个真正的设备上测试这一点,因为模拟器有后台任务处理问题。
我有一种感觉,这问题是特定于扩展,因为代码看起来好像没什么问题;这可能是Quinn的问题。询问开发者论坛。就一般提示而言,没有理由在主线程上运行会话回调;您已经将一个关键回调调度到主线程中。只是通过零。但我很确定这不是你问题的原因。 – dgatwood