2015-12-14 9 views
5

Alamofireは、1回のリクエストで複数の大きなファイルをダウンロードするために使用されています。 は私がセッション全体のダウンロードの進行状況Alamofire

Alamofire.request(.GET, imageURL).progress 

を使用して個別ファイルごとに見ることが進捗状況を作ることができるが、私は一度にすべてのオープンセッションの進行状況を追跡し、それを行う方法がわからないしたいと思います。 (私は15ファイルが同時にダウンロードしていると言うことができます) 私は単一のファイルの進捗状況に対処する多くのチュートリアルを読んでいますが、セッション全体ではありません。

は、それがどのように、Alamofireでそのように進行し、それがある場合に追跡することは可能ですか?

答えて

4

iOS9では、独自のNSProgressオブジェクトを作成し、たとえばfractionCompletedを確認できます。次に、あなたがaddChildできる:あなたはiOSの7/8のサポートが必要な場合

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

} 

、あまりにも、あなたはbecomeCurrentWithPendingUnitCountresignCurrentを呼び出すことができます。

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

あなたがAFNetworkingを使用している場合、それは同じですプロセスではなく、Alamofire progressプロパティを取得するよりも(上記と同じviewDidLoadobserveValueForKeyPath、およびdeinit方法IE)、あなたの代わりにAFHTTPSessionManagerメソッドを使用しますdownloadProgressForTaskを入力してNSURLSessionTaskに関連付けられたNSProgressを取得します。たとえば、次のように

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

あるいは、ダウンロードタスク使用している場合:

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() 
    } 
} 
+0

グレートおかげで、それは魔法のように動作します。 –

+0

こんにちは、Rob、AFNetworking 3.0で複数のファイルダウンロードの進捗状況を例示できますか? – Nuibb

+1

@Nuibb - これは本当に別の質問であるべきですが、私はAFNetworkingの例を示す私の答えを更新しました... – Rob

関連する問題