整个会话下载进度Alamofire

Jer*_*lic 6 ios nsurlsession swift alamofire

Alamofire用于一次请求下载多个较大的文件.我能够分别使用每个文件看到进展

Alamofire.request(.GET, imageURL).progress
Run Code Online (Sandbox Code Playgroud)

但我想立即跟踪所有公开会议的进展情况,不知道如何做到这一点.(假设我有15个文件同时下载)我读了很多教程来解决单个文件的进度,但整个会话没有.

是否有可能通过Alamofire跟踪进展,如果是,如何?

Rob*_*Rob 5

在iOS9中,您可以创建自己的NSProgress对象并观察,例如fractionCompleted. 然后你可以addChild

private var observerContext = 0

class ViewController: UIViewController {

    private var progress: NSProgress!

    override func viewDidLoad() {
        super.viewDidLoad()

        progress = NSProgress()
        progress.addObserver(self, forKeyPath: "fractionCompleted", options: .New, context: &observerContext)

        downloadFiles()
    }

    deinit {
        progress?.removeObserver(self, forKeyPath: "fractionCompleted")
    }

    private func downloadFiles() {
        let filenames = ["as17-134-20380.jpg", "as17-140-21497.jpg", "as17-148-22727.jpg"]

        let baseURL = NSURL(string: "http://example.com/path")!

        progress.totalUnitCount = Int64(filenames.count)
        progress.completedUnitCount = 0

        for filename in filenames {
            let url = baseURL.URLByAppendingPathComponent(filename)
            let childProgress = Alamofire.request(.GET, url.absoluteString)
                .response() { request, response, data, error in
                    // process response
                }
                .progress
            progress.addChild(childProgress, withPendingUnitCount: 1)
        }
    }

    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        if context == &observerContext {
            if keyPath == "fractionCompleted" {
                let percent = change![NSKeyValueChangeNewKey] as! Double
                print("\(percent)")
            }
        } else {
            super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

如果您也需要 iOS 7/8 的支持,您可以becomeCurrentWithPendingUnitCount致电resignCurrent

for filename in filenames {
    let url = baseURL.URLByAppendingPathComponent(filename)
    progress.becomeCurrentWithPendingUnitCount(1)
    Alamofire.request(.GET, url.absoluteString)
        .response() { request, response, data, error in
            // process response
    }
    progress.resignCurrent()
}
Run Code Online (Sandbox Code Playgroud)

如果您使用 AFNetworking,它是相同的过程(即与上面相同的viewDidLoadobserveValueForKeyPathdeinit方法),但不是检索 Alamofireprogress属性,而是使用该AFHTTPSessionManager方法downloadProgressForTask来获取NSProgressNSURLSessionTask. 例如:

private func getFiles() {
    let filenames = ["as17-134-20380.jpg", "as17-140-21497.jpg", "as17-148-22727.jpg"]

    let manager = AFHTTPSessionManager()
    manager.responseSerializer = AFHTTPResponseSerializer()

    let baseURL = NSURL(string: "http://example.com/path")!

    progress.totalUnitCount = Int64(filenames.count)
    progress.completedUnitCount = 0

    for filename in filenames {
        let url = baseURL.URLByAppendingPathComponent(filename)
        let task = manager.GET(url.absoluteString, parameters: nil, progress: nil, success: { task, responseObject in
            // do something with responseObject
            print(url.lastPathComponent! + " succeeded")
        }, failure: { task, error in
            // do something with error
            print(error)
        })

        if let downloadTask = task, let childProgress = manager.downloadProgressForTask(downloadTask) {
            progress.addChild(childProgress, withPendingUnitCount: 1)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,如果使用下载任务:

private func downloadFiles() {
    let filenames = ["as17-134-20380.jpg", "as17-140-21497.jpg", "as17-148-22727.jpg"]

    let manager = AFHTTPSessionManager()

    let baseURL = NSURL(string: "http://example.com/path")!

    progress.totalUnitCount = Int64(filenames.count)
    progress.completedUnitCount = 0

    let documents = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)

    for filename in filenames {
        let url = baseURL.URLByAppendingPathComponent(filename)
        let task = manager.downloadTaskWithRequest(NSURLRequest(URL: url), progress: nil, destination: { (temporaryURL, response) -> NSURL in
            return documents.URLByAppendingPathComponent(url.lastPathComponent!)
        }, completionHandler: { response, url, error in
            guard error == nil else {
                print(error)
                return
            }

            if let name = url?.lastPathComponent {
                print("\(name) succeeded")
            }
        })

        if let childProgress = manager.downloadProgressForTask(task) {
            progress.addChild(childProgress, withPendingUnitCount: 1)
        }

        task.resume()
    }
}
Run Code Online (Sandbox Code Playgroud)