1

我有以下问题.. 我用我的所有函数创建了一个 API 类,当 url 请求完成时它们返回结果。

我想在发出请求之前制作一个加载器,并在完成后将其删除。

我的请求代码是这样的:

-(NSDictionary *)makeApiCall:(NSString *)function params:(NSDictionary *)params view:(UIView *)displayView{

__block NSDictionary *json = nil;

[self makeRequestTo:function parameters:params successCallback:^(id jsonResponse) {
    json = jsonResponse;
} errorCallback:^(NSError *error, NSString *errorMsg) {
    NSLog(@"Error: %@", errorMsg);
}];


return json;

}


- (void) makeRequestTo:(NSString *) function
        parameters:(NSDictionary *) params
   successCallback:(void (^)(id jsonResponse)) successCallback
     errorCallback:(void (^)(NSError * error, NSString *errorMsg)) errorCallback {

NSURLResponse *response = nil;
NSError *error = nil;

AppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate setLoadingEnabled:true]
NSURL *url = [NSURL URLWithString:kBaseUrl];

AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];

httpClient.parameterEncoding = AFFormURLParameterEncoding;

NSMutableURLRequest *request = [httpClient requestWithMethod:@"POST" path:[NSString stringWithFormat:@"%@/%@",kApiBaseUrl,function] parameters:params];

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

//NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    if(error) {
        errorCallback(error, nil);
    } else {
        id JSON = AFJSONDecode(data, &error);
        successCallback(JSON);
    }
}];

}

但是..这行不通。加载器仅在请求完成后出现,并在一秒钟内被删除。

有趣的是,如果我从这个 Api 类中调用它,它会起作用.. 任何人都可以帮助我吗?

谢谢

4

1 回答 1

2

只有当程序控制返回到主运行循环时,才对用户界面进行更新。但是同步调用

NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

阻塞主线程并且在请求完成之前不返回。因此没有完成 UI 更新,特别是您的加载程序没有显示。

您可以sendAsynchronousRequest改用并在完成块中处理响应(并隐藏加载程序),因此代码大致如下所示:

- (void) makeRequestTo:(NSString *) function
            parameters:(NSDictionary *) params
       successCallback:(void (^)(id jsonResponse)) successCallback
         errorCallback:(void (^)(NSError * error, NSString *errorMsg)) errorCallback {

    AppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
    [appDelegate showLoader];

    // ... create request ...

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
        [appDelegate hideLoader];

        // ... handle response ...

    }];
}

但是您的方法还有另一个问题makeApiCall:由于异步makeRequestTo:工作,它几乎立即返回。当请求完成时,稍后会调用完成块。因此,变量将始终为。json = jsonResponse;jsonnil

没有办法解决这个问题。您不能在不阻塞线程的情况下将异步调用包装到同步方法中。特别是makeApiCall: 不能返回响应字典。您将不得不更改程序逻辑以异步工作。

于 2013-06-02T15:38:11.483 回答