magic_9527
magic_9527

Reputation: 295

How to improve the speed while using NSURLSessionDownloadTask?

I need to download some images and a video from server:

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
for (int i = 0; i < _collectionArr.count; ++i) {

    NSURL *URL = [NSURL URLWithString:URL_ADDRESS(portNumber,_collectionArr[i])];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];

    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil 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) {

        NSLog(@"File downloaded to: %@", filePath);
        if (i == _collectionArr.count - 1) {
            [SVProgressHUD showSuccessWithStatus:@"Done"];
        }

    }];
    [downloadTask resume];
}

I found that it is so slow! The speed is about 200K/s and the time with Android is 2/3 less than iPhone. When I download a mp4 about 4.6M, it takes 15s.

2014-11-29 13:46:35.071 testDownload[2105:47825] Begin
2014-11-29 13:46:51.740 testDownload[2105:47825] File downloaded to: file:///Users/apple/Library/Developer/CoreSimulator/Devices/259F2CB8-01FD-47C2-A38F-6100A2FF350A/data/Containers/Data/Application/71E553BC-F85D-4BFA-8937-FE9026FDF65C/Documents/VTS_01_audi.mp4

But when I using other app to download movies it can be 2M/s. Am I wrong when I use afnetworking ? How it happens and what can I do to deal with it. Another question is that I know it's wrong to monitor the last request with if (i == _collectionArr.count - 1){[SVProgressHUD showSuccessWithStatus:@"Done"];} But I don't know the right answer.

Thanks for your help.

Upvotes: 2

Views: 902

Answers (1)

Rob
Rob

Reputation: 437917

A couple of thoughts:

  1. The removal of the HUD when i hits count - 1 is not correct. You actually may remove it before they're all done. If you start two downloads, one huge one and one tiny one, the HUD will be dismissed when the second one finishes, but the other one might not be done yet. These run concurrently, so you have to wait until they're all done, not just when the last submitted one is done.

    One way to do this is to use a dispatch group (which you enter as you submit the requests, leave in the completion block, and then add a dispatch group notification that removes the HUD).

  2. You're not doing anything else outside of this code that might be blocking the main thread are you? AFNetworking dispatches its completion blocks to the main queue, and if you block the main thread for anything, it will affect this performance. You could either use Instruments to identify waiting threads, or, for testing purposes only, temporarily change the completionQueue of the manager to be some custom queue of your own creation.

    For example, before your for loop, do something like:

    manager.completionQueue = dispatch_queue_create("com.example.app.netCompletionQueue", NULL);
    

    That would take main thread blocking out of the equation (though this strikes me as unlikely unless you're doing something extraordinary in the main thread). Once you confirm this is not the issue, though, comment out that line, because you really do want to use the main thread for your completion blocks.

  3. Once you confirm the perf problem is not result on main thread contention issue, I'd suggest doing some benchmarking of alternative techniques (e.g. your own NSURLSession, etc.). This could help diagnose whether the problem is AFNetworking, rather than something like simulator vs device performance, caching, etc. Frankly, I find it unlikely that AFNetworking is, itself, the problem, though.

Upvotes: 2

Related Questions