Ожидание асинхронного запроса перед выполнением другого кода

#ios #xcode8 #nsurlsessiondownloadtask

#iOS #xcode8 #nsurlsessiondownloadtask

Вопрос:

Я использую [NSURLSession sharedSession] dataTaskWithRequest для получения данных с веб-сервера и отображения их в изображениях кнопок label amp; set в соответствии с ними, но моя проблема в том, что сначала выполняется код метки, и они отображаются как пустые, а затем завершается асинхронный блок кода.

 if(![self connected])
   {
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    arrMyres = [[NSMutableArray alloc] initWithArray:[prefs objectForKey:@"Myres"]];
   }

   else
   {

    // POSTrequest with URL to get data from server
    [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:
                             ^(NSData * _Nullable responseData,
                               NSURLResponse * _Nullable urlResponse,
                               NSError * _Nullable error) {
     if (error) {
        //Display error
                }
             else
                {
                     NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)urlResponse;
                    if([httpResponse statusCode ]>=200 amp;amp; [httpResponse statusCode]<300)
                     {
                       dispatch_async(dispatch_get_main_queue(), ^{
                       NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:amp;error];
                              
                    NSArray *array=[[dataDictionary objectForKey:@"GetExistingFavorites"] isKindOfClass:[NSNull class]]? nil:[dataDictionary objectForKey:@"GetExistingFavorites"];
                              
                     arrMyres=[[NSMutableArray alloc]initWithArray:array];
                       });
                    }
                }

           }] resume];
        }

//This block of code executes first and displays empty label
   if([arrMyres count]>0 )
   {
    //Set Button Image and display label 
   }
   else
   { 
    // Do something else
    } 
  

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

Любые предложения были бы полезны.

Ответ №1:

Обновите firstLabel код пользовательского интерфейса внутри асинхронного кода с помощью основного потока. См. Приведенный ниже код

 if(![self connected])
{
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    arrMyres = [[NSMutableArray alloc] initWithArray:[prefs objectForKey:@"Myres"]];
    [self updateUI];
}
else
{
    // POSTrequest with URL to get data from server
    [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:
    ^(NSData * _Nullable responseData,
    NSURLResponse * _Nullable urlResponse,
    NSError * _Nullable error) {
    if (error) {
    //Display error
    }
    else
    {
        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)urlResponse;
        if([httpResponse statusCode ]>=200 amp;amp; [httpResponse statusCode]<300)
        {
            dispatch_async(dispatch_get_main_queue(), ^{
            NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:amp;error];

            NSArray *array=[[dataDictionary objectForKey:@"GetExistingFavorites"] isKindOfClass:[NSNull class]]? nil:[dataDictionary objectForKey:@"GetExistingFavorites"];

            arrMyres=[[NSMutableArray alloc]initWithArray:array];
            //This block of code executes first and displays empty label
            if([arrMyres count]>0 )
            {
                [self updateUI];
            }
        }
    }

    }] resume];
}

-(void)updateUI {
    dispatch_async(dispatch_get_main_queue(), ^{
//update UI in main thread.
//Add your ui updates
    });
}
  

Комментарии:

1. Но что, если сначала он не вводит код блока else , затем UILabel выполняется после thisif(! [самостоятельное подключение]) { NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; arrMyres = [[NSMutableArray alloc] initWithArray:[prefs objectForKey:@»Myres»]]; } В этом случае перемещение UILabel обновление кода в асинхронном блоке не будет работать

2. Перед вызовом службы установите первый текст метки как пустой или загружаемый текст, после получения ответа от api покажите текст результата. Если arrMyres.count равно 0, тогда не отображается текст с найденными записями.