swift - 当应用程序在 iOS12 中进入后台时,URLSessionDelegate 的 didWriteData 不调用

标签 swift download ios12

我想实现下载功能,可以用百分比显示下载任务的完成状态。我能够做到这一点,但问题是当应用程序移动到后台并回到前台时,委托(delegate)方法 didWriteData 未在 iOS12。谁能帮帮我吗?这是我的代码

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

最佳答案

基于 this thread这是 NSURLSession 中的错误。目前有已知的解决方法(经 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() }
    }
}

关于swift - 当应用程序在 iOS12 中进入后台时,URLSessionDelegate 的 didWriteData 不调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53443652/

相关文章:

ios - 如何快速为整个应用程序的 UITextField 设置全局占位符颜色?

ios - 从当前上下文中继续时缺少选项卡栏

download - 不同站点之间下载速度差异巨大

ios - 在 iOS 中阅读短信

ios - Xcode 10 GM libstdc++ 错误,无法在模拟器上运行

ios - 如何使用 SDWebImage 从 URL 下载图像,然后将这些图像附加到 UIImage 数组?

iphone - 返回主视图 Controller ?

python - 使用 Python 从 cloudflare 网站下载文件

iOS - 下载文件时的渐进式下载指示器

objective-c - iOS 12.0 替代使用已弃用的 archiveRootObject :toFile: