Objective c NSURLSession uploadTaskWithRequest-在完成处理程序中使用块

Objective c NSURLSession uploadTaskWithRequest-在完成处理程序中使用块,objective-c,objective-c-blocks,nsurlsession,Objective C,Objective C Blocks,Nsurlsession,我有一个类,它管理对api的所有调用。 它有一个方法来管理它,让我们调用这个callAPIMethod: 此方法接受成功和失败块 在这个方法中,我调用uploadTaskWithRequest来调用API。 在uploadTaskWithRequest completion处理程序中,我希望(根据结果)将结果传递回success或fail块 我对此有些问题。它可以正常工作并保持一切超级整洁,但是当我使用success/fail块调用callAPIMethod时,它会锁定UI/main线程,而不是

我有一个类,它管理对api的所有调用。 它有一个方法来管理它,让我们调用这个
callAPIMethod:

此方法接受
成功
失败

在这个方法中,我调用
uploadTaskWithRequest
来调用API。 在uploadTaskWithRequest completion处理程序中,我希望(根据结果)将结果传递回
success
fail

我对此有些问题。它可以正常工作并保持一切超级整洁,但是当我使用success/fail块调用
callAPIMethod
时,它会锁定UI/main线程,而不是像我预期的那样异步

我应该如何实现这个模式?还是有更好的办法

我不需要支持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):


您的
NSURLSession
代码看起来不错。我建议添加一些断点,这样您就可以确定它是否在某个地方死锁,如果是,在哪里死锁。但此代码示例中没有任何内容会提示任何此类问题


我建议您确保所有UI调用都被分派回主队列。可以在后台队列上调用此
NSURLSessionUploadTask
完成处理程序,但所有UI更新(警报、导航、更新
UIView
控件等)必须在主队列上进行

编辑以添加代码。我认为这是一种可以接受的方式,所以可能会做一些完全愚蠢的事情。这对于调度到主线程来说是一个很好的观点。成功后,我将向导航堆栈中推送一个新的视图控制器。我猜我应该把它也发送到主线程吗<代码>显示错误消息显示alertView,尽管UI已锁定,但无论是否存在错误。谢谢!正如我所想,这是一个愚蠢的错误。我认为如果不是在主线程上,它会崩溃。。。而不是仅仅等待10秒以上。
[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];
                     }];