2013-02-17 5 views
0

Я пытаюсь сделать приложение iOS, которое общается с API, используя AFHTTPClient. Первый шаг авторизуйтесь пользователем, чтобы сделать это, я использую этот код:Ожидание завершения AFHTTPRequestOperation перед продолжением

-(void)authorize 
{ 
    NSURLRequest *request = [httpClient requestWithMethod:@"POST" path:@"login.php" parameters:@{@"login": account.username, @"passwd":account.password}]; 

    AFHTTPRequestOperation *operation = [httpClient HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) { 
     [httpClient setDefaultHeader:@"Token" value:[[operation.response allHeaderFields] objectForKey:@"CSRF-Token"]]; 
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
     NSLog(@"%@",error.localizedDescription); 
    }]; 
    [httpClient enqueueHTTPRequestOperation:operation]; 
    [httpClient.operationQueue waitUntilAllOperationsAreFinished]; 
} 

Как вы можете видеть, мой код получает маркер из ответа сервера и устанавливает его в качестве заголовка по умолчанию для всех будущих запросов ,

Я затем перейти на другие запросы, используя - (void)postPath:(NSString *)path parameters:(NSDictionary *)parameters success:success failure:failure

Но когда я использовал отладчик, я обнаружил, что те, другие запросы, где выполняются перед операцией авторизированным была завершена, поэтому они не потому, что они не имеют авторизации маркер. Я добавил [httpClient.operationQueue waitUntilAllOperationsAreFinished];, но это не похоже на работу ...

Спасибо за вашу помощь

+0

Не используйте 'wait', пока ничего не будет функционировать. Блокируйте приложение до завершения сетевого подключения. Просто поместите необходимый код в блок 'success' и вызовите' displayNextView' после его завершения. –

ответ

2

используйте устройство dispatch semaphore.

-(void)authorize 
{ 
    dispatch_semaphore_t done = dispatch_semaphore_create(0); 
    NSURLRequest *request = [httpClient requestWithMethod:@"POST" path:@"login.php" parameters:@{@"login": account.username, @"passwd":account.password}]; 

    AFHTTPRequestOperation *operation = [httpClient HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) { 
     [httpClient setDefaultHeader:@"Token" value:[[operation.response allHeaderFields] objectForKey:@"CSRF-Token"]]; 
     dispatch_semaphore_signal(done); 
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
     NSLog(@"%@",error.localizedDescription); 
    }]; 
    [httpClient enqueueHTTPRequestOperation:operation]; 
    [httpClient.operationQueue waitUntilAllOperationsAreFinished]; 
    dispatch_semaphore_wait(done, DISPATCH_TIME_FOREVER); 
} 

Обратите внимание, что это будет блокировать метод возвращаться, так что вам нужно, чтобы убедиться, что это не в главном потоке/UI.

+0

Что вы подразумеваете, блокируя метод возврата? – Abel

+0

Я пытался использовать его как это: 'dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_LOW, 0),^{ \t \t \t \t [API авторизации]; \t}); \t [api requestMethod: @ "users"]; ' Но он по-прежнему не работает, запросMethod вызывается до – Abel

+0

Вы должны сделать последующие запросы в том же потоке (или заблокированы блокировкой/семафором:'^{[api authorize]; [api doOtherRequests];} '. При необходимости вы можете создать очереди и просто методы очереди до тех пор, пока не будет выполнен авторизационный вызов. – Kevin

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