0

不叫我的行动扩展(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也实现了URLSessionDelegateURLSessionDownloadDelegate来处理下载的更新。

特别有趣的是

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)") 
    } 
} 

两个urlSessionDidFinishEventsdidFinishDownloadingTo不被称为handleEventsForBackgroundURLSession得到了在后台称为后。只有在将应用程序重新启动到前台后,才能调用委托方法。

为什么他们没有得到所谓的,我能做些什么来解决这个问题?

我试图创造handleEventsForBackgroundURLSessionURLSession这样的:

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 
} 

但是这并没有解决问题。

之前你问:是的,我是一个真正的设备上测试这一点,因为模拟器有后台任务处理问题。

+0

我有一种感觉,这问题是特定于扩展,因为代码看起来好像没什么问题;这可能是Quinn的问题。询问开发者论坛。就一般提示而言,没有理由在主线程上运行会话回调;您已经将一个关键回调调度到主线程中。只是通过零。但我很确定这不是你问题的原因。 – dgatwood

回答