2013-09-10 2 views
0

Я начинаю с iOS, и я пытаюсь закодировать простой файловый загрузчик с веб-просмотром.Как управлять активными операциями в AFNetworking (AFDownloadRequestOperation)

Мне нужно загрузить несколько файлов, но не вызывать одновременно (например, примеры, которые я видел); Он должен быть точно так же, как и настольный браузер: он должен иметь возможность добавлять новую операцию во время просмотра в любое время, а не все загрузки в строке ...

После прочтения и чтения я обнаружил, что в сети, и я «Я пытался реализовать его без каких-либо хороших результатов ... потому что я не знаю, как управлять несколькими операциями!

Вопрос в том, как только я добавил много операций, как я могу их назвать индивидуально? Например, чтобы остановить или отменить только один из них.

Это код:

... 
    AFHTTPClient *httpClient; 
... 


- (void)DownloadFileFromUrl:(NSString *)fileURL{ 

     NSURL *url = [NSURL URLWithString:fileURL]; 
     NSURLRequest *request = [NSURLRequest requestWithURL:url]; 

    //I've tried to init httpClient here each time, or at didLoad with a nil baseurl 

    httpClient =[[AFHTTPClient alloc]initWithBaseURL: [NSURL URLWithString:@"fileURL"]]; 
    [httpClient.operationQueue setMaxConcurrentOperationCount:10]; 

    AFDownloadRequestOperation *operation = [[AFDownloadRequestOperation alloc] initWithRequest:request 
                        targetPath:targetPath 
                        shouldResume:YES]; 


     [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 

      //COOL! 

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


      //remove the file if saved a part of it! 
      NSFileManager *fileManager = [NSFileManager defaultManager]; 
      [fileManager removeItemAtPath:targetPath error:&error]; 

      if (error) { 

       //ERROR 

      } 

      if ([operation isCancelled]) { 



      } 
     }]; 

    [operation setProgressiveDownloadProgressBlock:^(AFDownloadRequestOperation *operation1, NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpected, long long totalBytesReadForFile, long long totalBytesExpectedToReadForFile) 
    { 



      if (totalBytesExpectedToReadForFile > 0) { 
      dispatch_async(dispatch_get_main_queue(), ^{ 


       //NSLog(@"Operation%i: bytesRead: %d", 1, bytesRead); 
       //NSLog(@"Operation%i: totalBytesRead: %lld", 1, totalBytesRead); 
       //NSLog(@"Operation%i: totalBytesExpected: %lld", 1, totalBytesExpected); 
       //NSLog(@"Operation%i: totalBytesReadForFile: %lld", 1, totalBytesReadForFile); 
       //NSLog(@"Operation%i: totalBytesExpectedToReadForFile: %lld", 1, totalBytesExpectedToReadForFile); 



      }); 
     } 

    }]; 


     [httpClient.operationQueue addOperation:operation]; 
     //OR ?[httpClient enqueueHTTPRequestOperation:operation]; 


} 

Когда я скачать только один файл, кажется, все в порядке, потому что вызов httpClient.operationQueue.operations [0] ... Я получаю данные, и я могу Не делайте, из любого места, [[httpClient.operationQueue.operations [0]] пауза];

Однако, если я попытаюсь загрузить второй файл с другого сайта (у меня есть веб-просмотр для навигации) и добавьте его в httpClient.operationQueue, он, похоже, не добавит его в ту же очередь; Я имею в виду, если я позвоню с таймером это:

NSLog(@"Operations %d", httpClient.operationQueue.operations.count); 

Я не получить «Операции 2», но:

Operations 1 
Operations 1 

Это раздражает, потому что иногда, когда я пытаюсь получить operations.count в чтобы найти мою желаемую операцию и что-то сделать с ней, я не нахожу ее! Он находится в «параллельной» очереди или что-то в этом роде!

Это способ получить и обработать все активные операции? Или способ хранить каждую операцию на каком-то массиве каждый раз, когда я добавляю один? (но возможность «использовать их», а не для целей, предназначенных только для чтения, например, для вызова паузы, отмены и т. д.)

Очевидно, что мне не хватает чего-то важного и что я новичок в программировании, но любая помощь будет действительно оценена! (и, пожалуйста, если вы можете быть явным, гораздо лучше .. Я новичок)

Большое спасибо, действительно.

EDIT: После этого небольшого исследования, и пытаются некоторые вещи, я решил, что, добавив, что HttpClient к одноэлементному, и установить его только тогда, когда приложение инициализирует, со случайным BaseUrl. Затем я добавляю каждую операцию в этот Singleton-httpClient, несмотря на его url. Кажется, что он работает, потому что теперь он хранит все коннекты, и я могу получить к ним доступ, теперь проблемы с ним зацикливаются, но я знаю, что это не очень хорошо; он должен быть проще на чистом, и я знаю, что мне не хватает способа управления активными соединениями в каком-то массиве вместо использования «сложного» httpclient с поддельным baseurl для всех операций (с разными URL-адресами) So ... Я все еще принимаю советы и хорошие практики :). Благодаря!

ответ

3

Хорошо несколько советов перед рукой. я настоятельно рекомендую вам прочитать как NSOperationQueue и NSOperation API документ:

NSOperationQueue: https://developer.apple.com/library/ios/documentation/Cocoa/Reference/NSOperationQueue_class/Reference/Reference.html#//apple_ref/doc/uid/TP40004592

NSOperation: https://developer.apple.com/library/ios/documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.html#//apple_ref/doc/uid/TP40004591

Я разочаровать вас, чтобы попытаться перебрать массив операций NSOperationQueue в. Зачем? Поскольку, вероятно, вы закончите с проблемой состояния гонки.

Однако. Я предлагаю вам следующий подход:

1) Создать NSDictionary в своем классе, где одноплодном: ключ: будет представлять собой имя файла значения: запрос ассоциированного AFDownloadRequestOperation с этой просьбой.

2) Когда вам нужно скачать новый файл: Проверьте, существует ли в вашем словаре, если не создается новая операция и не добавляется в словарь.

2.1) Если это действительно существует, вы можете: 2.1.1) Поскольку AFDownloadRequestOperation распространяется из NSOperation, вы можете отменить его. Чтобы сделать это, прежде чем вы должны проверить эти условия: isExecuting, isFinished. Если какое-либо из этих условий ложно, вы можете отменить операцию и удалить ее из своего словаря.

+0

@ user1450188 это вам помогло? – rodchile

Смежные вопросы