当应用程序在 iOS12 中进入后台时,URLSessionDelegate 的 didWriteData 不会调用
Posted
技术标签:
【中文标题】当应用程序在 iOS12 中进入后台时,URLSessionDelegate 的 didWriteData 不会调用【英文标题】:URLSessionDelegate's didWriteData not call when app is going to background in iOS12 【发布时间】:2018-11-23 09:14:19 【问题描述】:我想实现下载功能,可以用百分比显示下载任务的完成状态。我能够做到这一点,但问题是当应用程序移动到后台并回到前台时,ios12
中没有调用委托方法didWriteData
。谁能帮帮我吗?这是我的代码
protocol DownloadDelagate
func downloadingProgress(value:Float)
func downloadCompleted(identifier: Int,url: URL)
class DownloadManager : NSObject, URLSessionDelegate, URLSessionDownloadDelegate
static var shared = DownloadManager()
var delegate: DownloadDelagate?
var backgroundSessionCompletionHandler: (() -> Void)?
var session : URLSession
get
let config = URLSessionConfiguration.background(withIdentifier: "\(Bundle.main.bundleIdentifier!).background")
config.isDiscretionary = true
config.sessionSendsLaunchEvents = true
return URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue())
private override init()
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession)
DispatchQueue.main.async
if let completionHandler = self.backgroundSessionCompletionHandler
self.backgroundSessionCompletionHandler = nil
completionHandler()
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL)
delegate?.downloadCompleted(identifier: downloadTask.taskIdentifier, url: location)
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64)
if totalBytesExpectedToWrite > 0
let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
let progressPercentage = progress * 100
delegate?.downloadingProgress(value: progressPercentage)
print("Download with task identifier: \(downloadTask.taskIdentifier) is \(progressPercentage)% complete...")
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
if let error = error
print("Task failed with error: \(error)")
else
print("Task completed successfully.")
【问题讨论】:
获取一个代表您的 DownloadManger 的对象。在该对象类中添加deinit print("class deinited")
。现在,当您进入后台时,请检查您的委托对象是否还活着。如果它被取消初始化,您将看到打印的语句。这基本上意味着你的弱引用被释放并且你的函数没有被触发,因为它没有委托。
你是在告诉func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64)
这个方法didWriteData
吗?
@Vicky_Vignesh 是的,这个方法。
【参考方案1】:
基于this thread,这是NSURLSesstion
中的一个错误。目前有已知的解决方法(经 Apple 工程师批准):
var session: URLSession?
...
func applicationDidBecomeActive(_ application: UIApplication)
session?.getAllTasks tasks in
tasks.first?.resume() // It is enough to call resume() on only one task
// If it didn't work, you can try to resume all
// tasks.forEach $0.resume()
【讨论】:
【参考方案2】:请在 AppDelegate 的 applicationWillEnterForeground()
中尝试您的代码。当应用程序从背景转换到活动状态时,您可以在此处进行更改。
【讨论】:
以上是关于当应用程序在 iOS12 中进入后台时,URLSessionDelegate 的 didWriteData 不会调用的主要内容,如果未能解决你的问题,请参考以下文章
当应用程序在 Tinder/Scarlet Websocket 中进入后台时保持 websocket 打开
当 FragmentActivity 在 Android 中进入后台时出现 NotSerializableException