How to get download progress in AFNetworking 2.0?

前端 未结 4 1458
一整个雨季
一整个雨季 2020-11-29 02:16

I am using AFURLSessionManager to create a new download task:

AFURLSessionManager* manager = ...

NSProgress* p = nil;
NSURLSessionDownloadTask* downloadTask         


        
相关标签:
4条回答
  • 2020-11-29 02:50

    Simple solutions for Swift:

    let sessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
    let sessionManager = AFURLSessionManager(sessionConfiguration: sessionConfiguration)
    let request = NSURLRequest(URL: url)
    let sessionDownloadTask = sessionManager.downloadTaskWithRequest(request, progress: nil, destination: { (url, response) -> NSURL in
    
                return destinationPath.URLByAppendingPathComponent(fileName) //this is destinationPath for downloaded file
    
                }, completionHandler: { response, url, error in
    
                    //do sth when it finishes
            })
    

    Now you have 2 options:

    1. Using UIProgressView and setProgressWithDownloadProgressOfTask:

      progressView.setProgressWithDownloadProgressOfTask(sessionDownloadTask, animated: true)
      
    2. Using AFURLSessionManager and setDownloadTaskDidWriteDataBlock:

      sessionManager.setDownloadTaskDidWriteDataBlock { session, sessionDownloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite in
      
          let progress = Float(totalBytesWritten)/Float(totalBytesExpectedToWrite)
              //do sth with current progress
      }
      

    At the end do not forget about:

    sessionDownloadTask.resume()
    
    0 讨论(0)
  • 2020-11-29 03:01

    For Download file with progress status use this code

     NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
    
    NSURL *URL = [NSURL URLWithString:@"http://..."];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];
    
    
    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress)
    {
        NSLog(@"Progress: %f", downloadProgress.fractionCompleted);
        if (progressBlock) {
                        progressBlock(downloadProgress);
                    }
    } destination:^NSURL *(NSURL *targetPath, NSURLResponse *response)
    {
        NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
        return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error)
    {
        if (response && successBlock) {
                        successBlock(response,filePath);
                    }
        NSLog(@"File downloaded to: %@", filePath);
    }];
    
    [downloadTask resume];
    
    0 讨论(0)
  • 2020-11-29 03:02

    You should observe the fractionCompleted property of your NSProgress object using KVO:

    NSURL *url = [NSURL URLWithString:@"http://www.hfrmovies.com/TheHobbitDesolationOfSmaug48fps.mp4"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    AFHTTPSessionManager *session = [AFHTTPSessionManager manager];
    NSProgress *progress;
    NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request progress:&progress destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
        // …
    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
        [progress removeObserver:self forKeyPath:@"fractionCompleted" context:NULL];
        // …
    }];
    
    [downloadTask resume];
    [progress addObserver:self
                forKeyPath:@"fractionCompleted"
                   options:NSKeyValueObservingOptionNew
                   context:NULL];
    

    Then add the observer method:

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    {
        if ([keyPath isEqualToString:@"fractionCompleted"]) {
            NSProgress *progress = (NSProgress *)object;
            NSLog(@"Progress… %f", progress.fractionCompleted);
        } else {
            [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
        }
    }
    

    Of course, you should check keyPath and/or object parameters to decide if that's the object/property you want to observe.

    You can also use the setDownloadTaskDidWriteDataBlock: method from AFURLSessionManager (from which AFHTTPSessionManager inherits) to set a block for receiving download progress updates.

    [session setDownloadTaskDidWriteDataBlock:^(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) {
        NSLog(@"Progress… %lld", totalBytesWritten);
    }];
    

    This AFNetworking method maps the URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite: method from NSURLSessionDownloadDelegate protocol to a more convenient block mechanism.

    BTW, Apple's KVO implementation is severely broken. I recommend using a better implementation like the one proposed by Mike Ash with MAKVONotificationCenter. If you are interested in reading why Apple's KVO is broken, read Key-Value Observing Done Right by Mike Ash.

    0 讨论(0)
  • 2020-11-29 03:08

    I faced a similar problem, and found a solution.

    Check the link below: http://cocoadocs.org/docsets/AFNetworking/2.0.1/Categories/UIProgressView+AFNetworking.html

    #import <AFNetworking/UIKit+AFNetworking.h>
    

    and use the additional method available to your UIProgressView

    setProgressWithDownloadProgressOfTask:animated:

    How I did it:

    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request  progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response){
        NSURL *documentsDirectoryPath = [NSURL fileURLWithPath:[NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES) firstObject]];
        return [documentsDirectoryPath URLByAppendingPathComponent:[targetPath lastPathComponent]];
    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error){
        NSLog(@"File downloaded to: %@", filePath);
    
    }];
    
    [self.progressView setProgressWithDownloadProgressOfTask:downloadTask animated:YES];
    [downloadTask resume];
    
    0 讨论(0)
提交回复
热议问题