在继续之前等待AFHTTPRequestOperation完成

时间:2013-02-17 20:26:49

标签: ios nsurlconnection afnetworking nsoperation

我正在尝试制作一个使用AFHTTPClient与API通信的iOS应用。第一步是对用户进行身份验证,为此,我使用此代码:

-(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

继续处理其他请求

但是当我使用调试器时,我发现在授权操作之前执行的那些其他请求已经完成,因此它们失败了,因为它们没有auth令牌。我添加了[httpClient.operationQueue waitUntilAllOperationsAreFinished];,但它似乎不起作用......

感谢您的帮助

1 个答案:

答案 0 :(得分: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线程上。