2016-12-19 8 views
0

Мне нужно загружать данные из нескольких URL-адресов синхронно, что необходимо сделать в фоновом потоке, чтобы это не повлияло на действия на лицевой панели. Я бы как использовать NSOpeartionQueue и NSURLSession. Сейчас я использую код ниже.Загрузка данных из нескольких URL-адресов в фоновом потоке с использованием NSOperationQueue синхронно

for (int i=0;i<[tempArray count];i++) { 
      CheckList * checklist = (CheckList *)[tempArray objectAtIndex:i]; 

     [operationQueue addOperationWithBlock:^{ 

      dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); 

      NSString * urlStr = [[BASE_URL stringByAppendingString:DOWNLOAD_CHECKLIST_METADATA_SUBURL] stringByAppendingFormat:@"%@/%d/%@",userName,[checklist.checklistId intValue],checklist.language]; 
      NSURL * url = [NSURL URLWithString:urlStr]; 
      NSLog(@"url is %@",url); 

      NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; 
      NSURLSession *session = [NSURLSession sessionWithConfiguration:config]; 

      NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:url]; 
      [request setTimeoutInterval:240.0]; 
      [request setValue:@"Application/JSON" forHTTPHeaderField:@"Content-Type"]; 
      NSURLSessionDataTask * downloadTask =[session dataTaskWithRequest:request completionHandler:^(NSData * data, NSURLResponse * response, NSError * error) 
                { 

                 NSString * str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
                 NSLog(@"response is %@",str); 
                }]; 
      [downloadTask resume]; 
      [indexSetBg addIndex:[checklist.checklistId intValue]]; 
      // but have the thread wait until the task is done 

      dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 


     }]; 

     } 

Но если я хочу, чтобы отправить запрос синхронно, есть ли способ для that.Means после получения 1-го ответа, второй запрос должен быть отправлен. Может кто-нибудь из вас, пожалуйста, помогите мне выполнить это.

спасибо, что заранее.

+0

Какова ваша текущая проблема? Что вы хотите продолжить делать после завершения загрузки или не хотите запускать загрузку до того, как она закончится? – shallowThought

ответ

0

вам необходимо добавить dispatch_semaphore_signal (семафор);

в конце вашего NSURLSessionTask завершения обработчика

for (int i=0;i<[tempArray count];i++) { 
     CheckList * checklist = (CheckList *)[tempArray objectAtIndex:i]; 

    [operationQueue addOperationWithBlock:^{ 

     dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); 

     NSString * urlStr = [[BASE_URL stringByAppendingString:DOWNLOAD_CHECKLIST_METADATA_SUBURL] stringByAppendingFormat:@"%@/%d/%@",userName,[checklist.checklistId intValue],checklist.language]; 
     NSURL * url = [NSURL URLWithString:urlStr]; 
     NSLog(@"url is %@",url); 

     NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; 
     NSURLSession *session = [NSURLSession sessionWithConfiguration:config]; 

     NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL:url]; 
     [request setTimeoutInterval:240.0]; 
     [request setValue:@"Application/JSON" forHTTPHeaderField:@"Content-Type"]; 
     NSURLSessionDataTask * downloadTask =[session dataTaskWithRequest:request completionHandler:^(NSData * data, NSURLResponse * response, NSError * error) 
               { 

                NSString * str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
                NSLog(@"response is %@",str); 
                dispatch_semaphore_signal(semaphore); 
               }]; 
     [downloadTask resume]; 
     [indexSetBg addIndex:[checklist.checklistId intValue]]; 
     // but have the thread wait until the task is done 

     dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 


    }]; 

    } 
+0

Моя проблема здесь в загрузке происходит один за другим. Но все запросы отправляются почти вместе. Таким образом, через секунду или два будут отправлены все запросы. Таким образом, к тому времени, как я нажму кнопку загрузки, запрос на этот конкретный URL может быть отправлен. – iOSManiac

+0

на вашем событии нажатия кнопки вы можете проверить задачи NSURLSession с помощью getTasksWithCompletionHandler для каждой задачи с данными, проверить его URL-адрес, посмотреть, соответствует ли он задаче задания, которое должно быть запущено при нажатии кнопки, если да, вы ничего не делаете если нет, вы можете загрузить с заданием, которое вы создаете в своем клике, и отключить операцию. для этого вы должны хранить словарь url (как ключ) и операцию как значение, чтобы вы могли отключить эту операцию, для предотвращения дублирования загрузки –

+0

см. этот пример getTaskWithCompletionHandler здесь: https: //gist.github.com/ sudeepjaiswal/4ed79ac947e4776d4aed –