0

I'm struggling to implement download mechanism for multiple files using AFNetworking. I want to download zip file one after another from multiple url with progression message. I tried like following code, but getting error as -

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSOperationQueue addOperation:]: operation is already enqueued on a queue'

Here is my code portion :

- (void) downloadCarContents:(NSArray *)urlArray forContent:(NSArray *)contentPaths {

    NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];

    for (int i=0; i< urlArray.count; i++) {

        NSString *destinationPath = [self.documentDirectory getDownloadContentPath:contentPaths[i]];

        NSLog(@"Dest : %@", destinationPath);

        AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
        AFHTTPRequestOperation *operation = [manager GET:urlArray[i]
                                              parameters:nil
                                                 success:^(AFHTTPRequestOperation *operation, id responseObject) {

                                                 } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

                                                     NSLog(@"Error : %ld", (long)error.code);
                                                 }];

        operation.outputStream = [NSOutputStream outputStreamToFileAtPath:destinationPath append:NO];

        [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
            float percentage = (float) (totalBytesRead * 100) / totalBytesExpectedToRead;
            [self.delegate downloadProgression:percentage];
        }];

        [operationQueue addOperation:operation];
    }
}

Please help.

Nuibb
  • 1,800
  • 2
  • 22
  • 36

1 Answers1

3

When you call GET, it's already added to the operationQueue of the AFHTTPRequestionOperationManager. So don't add it to a queue again.

Also, you should instantiate the AFHTTPRequestOperationManager once, before the loop, not repeated within the loop.


There are other problems with this code, but rather than trying to address all of these issues, I'd suggest you transition to AFHTTPSessionManager, which uses NSURLSession. The old AFHTTPRequestOperationManager was NSURLConnection-based, but NSURLConnection is now deprecated. And, in fact, AFNetworking 3.0 has retired AFHTTPRequestOperationManager entirely.

So, the AFHTTPSessionManager rendition might look like:

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

for (NSInteger i = 0; i < urlArray.count; i++) {
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlArray[i]]];
    NSURLSessionTask *task = [manager downloadTaskWithRequest:request progress:^(NSProgress *downloadProgress) {
        [self.delegate downloadProgression:downloadProgress.fractionCompleted * 100.0];
    } destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
        return [NSURL fileURLWithPath:[self.documentDirectory getDownloadContentPath:contentPaths[i]]];
    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
        NSLog(@"File downloaded to: %@", filePath);
        NSLog(@"Error: %@" error.localizedDescription);
    }];
    [task resume];
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • thanks, but how to implement progression block with NSURLSession ? – Nuibb Dec 13 '15 at 09:11
  • As well as can i make any dependency while downloading with this NSURLSession block ? i mean synchronizing one after another ? – Nuibb Dec 13 '15 at 09:16
  • Ya i'm struggling to implement NSProgress block. In your code, i got an error like "Sending 'void (^)(NSProgress *__strong)' to parameter of incompatible type 'NSProgress *__autoreleasing _Nullable * _Nullable' ". How to solve this ? And how to aggregate child NSProgress into one master NSProgress ? – Nuibb Dec 13 '15 at 09:33
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/97804/discussion-between-nuibb-and-rob). – Nuibb Dec 14 '15 at 04:41
  • One question more. How can i ensure in the completionHandler block that all the contents are successfully downloaded ? I need that validation in the completionHandler block but not in the observeValueForKeyPath method by checking 1.0 fraction value completion ? – Nuibb Mar 03 '16 at 06:18
  • If it was successful, the `NSError` will be `nil`. – Rob Mar 03 '16 at 06:50
  • Actually i wanted to check if all the contents of different url is downloaded or not. Finally I did it by counting each finished task with the total url count in completionHandler block. By the way, thank you very much for response. – Nuibb Mar 03 '16 at 08:15
  • Hi Rob, from your github page, "https://github.com/robertmryan/AFHTTPSessionOperation", how can i replace AFHTTPSessionOperation by Alamofire framework for swift ? – Nuibb Apr 24 '16 at 06:23