2

Swift で NSURLSession を使用して複数のファイルを同時にダウンロードしようとしています。すべてのファイルがダウンロードされたときに 100% を表示するように、すべてのダウンロードの進行状況を 1 つにマージしたいと考えています。現在、ファイルのダウンロードが完了するたびに 100% を取得していますが、すべてのファイルがダウンロードされた場合にのみ 100% が必要です。Swift でこれを達成するにはどうすればよいですか?

ここに私のDownloadManagerクラスがあります:

class DownloadManager : NSObject, URLSessionDelegate, URLSessionDownloadDelegate {

static var shared = DownloadManager()
var task1Progress = 0.00
var task2Progress = 0.00
typealias ProgressHandler = (Float) -> ()

var onProgress : ProgressHandler? {
    didSet {
        if onProgress != nil {
            let _ = activate()
        }
    }
}

override private init() {
    super.init()
}

func activate() -> URLSession {
    let config = URLSessionConfiguration.background(withIdentifier: "\(Bundle.main.bundleIdentifier!).background")

    // Warning: If an URLSession still exists from a previous download, it doesn't create a new URLSession object but returns the existing one with the old delegate object attached!
    return URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue())
}

func calculateProgress(session : URLSession, completionHandler : @escaping (Float) -> ()) {
    session.getTasksWithCompletionHandler { (tasks, uploads, downloads) in
        let progress = downloads.map({ (task) -> Float in
            if task.countOfBytesExpectedToReceive > 0 {
                return Float(task.countOfBytesReceived) / Float(task.countOfBytesExpectedToReceive)
            } else {
                return 0.0
            }
        })
        completionHandler(progress.reduce(0.0, +))
    }
}


func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {

    if totalBytesExpectedToWrite > 0 {
        if let onProgress = onProgress {
            calculateProgress(session: session, completionHandler: onProgress)
        }

        let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
        debugPrint("Download Progress \(downloadTask) \(progress)")

    }
}

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
    debugPrint("Download finished: \(location)")
    try? FileManager.default.removeItem(at: location)
}


func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
    debugPrint("Task completed: \(task), error: \(String(describing: error))")
}

private func calculateProgress(session : URLSession, completionHandler : @escaping (Float) -> ()) {
    session.getTasksWithCompletionHandler { (tasks, uploads, downloads) in
        let progress = downloads.map({ (task) -> Float in
            if task.countOfBytesExpectedToReceive > 0 {

                if (task.taskIdentifier ==  1) {

                    self.task1Progress = Double(Float(task.countOfBytesReceived) / Float(task.countOfBytesExpectedToReceive))

                } else if (task.taskIdentifier ==  2){

                    self.task2Progress = Double(Float(task.countOfBytesReceived) / Float(task.countOfBytesExpectedToReceive))

                }

                print("pro1 = \(self.task1Progress) pro2 = \(self.task2Progress)")

                if(self.task1Progress>0.0000 && self.task2Progress>0.000) {
                    return Float(min(self.task1Progress  ,self.task2Progress))
                }

                return Float(max(self.task1Progress  ,self.task2Progress))

            } else {

                return 0.0
            }
        })
        completionHandler(progress.reduce(0.0, +))
    }
}

}

4

4 に答える 4