How to download the large amount of data using AFN

2019-08-27 04:43发布

问题:

I am using AFNetworking Library, How to download the large amount of data using AFNetworking Library to show the better performance?

I have followed the following steps:

".zip" files downloading the content from server.

I have added one url , like this i have so many url's to download the content from the server. It takes too much time. How to perform the fast downloading from server.

My Query is: If the url was not found on server, then it executes failure state. but the ".zip" is storing in documents folder with empty content like zerobytes.

while am trying to extract the .zip it shows .cpgz format. Let us know how to resolve this?

-(void)downloadSingFile:(NSUInteger )activityAtIndex totalCount:(NSUInteger )lessonTotalCount{
    // http://118.102.131.158/IYG_wrapper/IYG_updated/IYG_G7_L03/IYG_UN_Mall.zip

    NSString *activityUrl = [filterObjects objectAtIndex:activityAtIndex];
    NSURL *zipFileAtUrl  = [NSURL URLWithString:[activityUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
    BOOL success = [libraryObj createFolderWithName:rootName];
    if (success) {
        activityPath = [[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:rootName] stringByAppendingPathComponent:[zipFileAtUrl lastPathComponent]];
    }
    NSURLRequest *request = [NSURLRequest requestWithURL:zipFileAtUrl];
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    operation.outputStream = [NSOutputStream outputStreamToFileAtPath:activityPath append:NO];

    [operation setCompletionBlock:^{
        sleep(1);
        NSLog(@"sucessfully downloaded file %d",activityIndx);
        [self extractSingleActivityAtindex:activityIndx];

    }];
    [operation start];

    [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
        float percentDone = ((float)(totalBytesRead) / (float)(totalBytesExpectedToRead));
        self.tableView.alpha = 0.7;
        progressView.hidden = NO;
        progressAlert.hidden = NO;
        progressAlert.labelText = @"Downloading..";
        [self updateProgress:percentDone];
        NSLog(@"progress float value is: %.2f",percentDone);
    }];

}

1.Please let us know, now i dont want to download the which is exist in documents folder path and also let us know whether the the file has been downloaded sucessfully or not.

回答1:

A couple of thoughts:

  1. If you want to know if it succeeded or not, rather than using setCompletionBlock, you should use setCompletionBlockWithSuccess:failure:.

  2. In a related topic, I might be inclined to download the file to some temporary file (in the NSTemporaryDirectory() folder) and only once it was successfully downloaded, move it to the Documents folder. You want to completely eliminate the possibility of any in-progress download resulting in a file in Documents.

  3. If you don't want to download a file that already exists in your Documents folder, then you have to program that logic yourself (i.e. use NSFileManager to see if the file exists, and if not, only then initiate the download).

  4. Eliminate the sleep call. You never want to sleep (esp on the main thread). If you really want to trigger something to happen one second later, use dispatch_after:

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"sucessfully downloaded file %d",activityIndx);
        [self extractSingleActivityAtindex:activityIndx];
    });
    


回答2:

You need to take care of below points to achieve your functionality

  1. Check file is already exist or not before download
  2. Implement failure block and remove file at your activityPath

For reference, please check below code snippet.

-(void)downloadSingFile:(NSUInteger )activityAtIndex totalCount:(NSUInteger )lessonTotalCount{
// http://118.102.131.158/IYG_wrapper/IYG_updated/IYG_G7_L03/IYG_UN_Mall.zip

NSString *activityUrl = [filterObjects objectAtIndex:activityAtIndex];
NSURL *zipFileAtUrl  = [NSURL URLWithString:[activityUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
BOOL success = [libraryObj createFolderWithName:rootName];
if (success) {
    activityPath = [[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:rootName] stringByAppendingPathComponent:[zipFileAtUrl lastPathComponent]];
}
 if ([[NSFileManager defaultManager]fileExistsAtPath:activityPath]) {
     NSLog(@"File Already Exist");
     [self extractSingleActivityAtindex:activityIndx];
     return;
 }
NSURLRequest *request = [NSURLRequest requestWithURL:zipFileAtUrl];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:activityPath append:NO];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    sleep(1);
    NSLog(@"sucessfully downloaded file %d",activityIndx);
    dispatch_async(dispatch_get_main_queue(), ^() {
       [self extractSingleActivityAtindex:activityIndx];
    });


} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    //    NSLog(@"ERR: %@", [error description]);
    [[NSFileManager defaultManager]removeItemAtPath:activityPath error:nil];

}];

[operation start];

[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
    float percentDone = ((float)(totalBytesRead) / (float)(totalBytesExpectedToRead));
    self.tableView.alpha = 0.7;
    progressView.hidden = NO;
    progressAlert.hidden = NO;
    progressAlert.labelText = @"Downloading..";
    [self updateProgress:percentDone];
    NSLog(@"progress float value is: %.2f",percentDone);
}];

}