Objective c MBProgressHUD和NSURL连接
我有以下问题。。 我用我所有的函数创建了一个API类,当url请求完成时,它们会返回结果 我想在发出请求之前创建一个加载程序,并在完成后将其删除 我的申请代码如下:Objective c MBProgressHUD和NSURL连接,objective-c,asynchronous,request,nsurlconnection,Objective C,Asynchronous,Request,Nsurlconnection,我有以下问题。。 我用我所有的函数创建了一个API类,当url请求完成时,它们会返回结果 我想在发出请求之前创建一个加载程序,并在完成后将其删除 我的申请代码如下: -(NSDictionary *)makeApiCall:(NSString *)function params:(NSDictionary *)params view:(UIView *)displayView{ __block NSDictionary *json = nil; [self makeRequestTo:fun
-(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类中调用它,它会工作。。
有人能帮我吗
谢谢只有当程序控制返回到主界面时,才会对用户界面进行更新 运行循环。但是同步呼叫
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的块代码>稍后在请求完成时调用。
因此,json
变量将始终为nil
这是没有办法的。不能将异步调用包装为同步调用
方法而不阻塞线程。特别是,makeApiCall:
无法返回
响应字典。
您必须更改程序逻辑才能工作
异步。结果相同。。还有什么建议吗/@蒂亚戈尔梅达:也许你可以将新代码添加到你的问题中,否则很难猜测问题可能在哪里。@蒂亚戈尔梅达:你的新代码不再包含showLoader
和hideLoader
,那么结果怎么可能是相同的??是否已替换为[appDelegate setLoadingEnabled:true]
?在这种情况下,其中是[appDelegate setLoadingEnabled:false]
?-但是您的代码还有一个基本问题,请参阅更新的答案。嗯,那么我如何包装这个呢?我需要显示加载程序并执行请求。请求完成后,移除加载程序并返回json。我该怎么做?@TiagoAlmeida:如果不阻止主线程并因此阻止所有用户界面更新,这是不可能的正如我所说,您应该更改程序逻辑以异步工作。例如,如果要在表视图中显示JSON响应,可以将获取的数据分配给makeRequestTo:…
的完成块中的表视图数据源,然后调用reloadData
。