【发布时间】:2014-04-07 04:16:56
【问题描述】:
我有一个类来管理对 api 的所有调用。
它有一个方法来管理这个,我们称之为callAPIMethod:
此方法接受 success 和 fail 块。
在这个方法中,我调用uploadTaskWithRequest 来调用一个API。
在 uploadTaskWithRequest 完成处理程序中,我想(取决于结果)将结果传递回 success 或 fail 块。
我遇到了一些问题。它可以工作并且保持一切都超级整洁,但是当我使用成功/失败块调用callAPIMethod 时,它会锁定 UI/MainThread,而不是像我期望的那样异步。
我应该如何实现这种模式?还是有更好的办法?
我不需要支持pre-iOS7。
谢谢
编辑:上面讨论的基本实现。
- (void)callApiMethod:(NSString *)method withData:(NSString *)requestData as:(kRequestType)requestType success:(void (^)(id responseData))success failure:(void (^)(NSString *errorDescription))failure {
[redacted]
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session uploadTaskWithRequest:request
fromData:postData
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
failure(error.description);
} else {
NSError *jsonError;
id responseData = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:&jsonError];
if (jsonError) {
failure(jsonError.description);
} else {
success(responseData);
}
}
}];
[task resume];
}
CallAPI 方法,使用如下(来自 UITableViewController):
[apiController callApiMethod:@"users.json?action=token"
withData:loginData
as:kRequestPOST
success:^(id responseData) {
if ([responseData isKindOfClass:[NSDictionary class]]) {
if ([responseData objectForKey:@"token"]) {
//Store token/credentials
} else if ([responseData objectForKey:@"error"]) {
//Error
[self displayErrorMessage:[responseData objectForKey:@"error"]];
return;
} else {
//Undefined Error
[self displayErrorMessage:nil];
return;
}
} else {
//Error
[self displayErrorMessage:nil];
return;
}
//If login success
}
failure:^(NSString *errorDescription) {
[self displayErrorMessage:errorDescription];
}];
【问题讨论】:
-
编辑添加代码。认为这是一种可以接受的方式,所以可能会做一些完全愚蠢的事情。
-
关于调度到主线程的好点。成功后,我将一个新的视图控制器推送到导航堆栈。猜猜我也应该将它发送到主线程?
displayErrorMessage显示一个 alertView,尽管无论是否有错误,UI 都会被锁定。 -
谢谢!正如我所想,一个愚蠢的错误。我假设如果不在主线程上它会崩溃......而不是仅仅挂起 10 多秒。
标签: objective-c objective-c-blocks nsurlsession