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

时间:2021-04-05 21:00:51

I have a class which manages all calls to an api. It has a method to manage this, lets call this callAPIMethod:

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

This method accepts a success and fail block.

此方法接受成功和失败块。

Inside this method, I call uploadTaskWithRequest to make a call to an API. Within the uploadTaskWithRequest completion handler I'd like to (depending on the result) pass results back through to either the success or fail blocks.

在这个方法中,我调用uploadTaskWithRequest来调用API。在uploadTaskWithRequest完成处理程序中,我希望(取决于结果)将结果传递回成功或失败块。

I'm having some issues with this. It works and is keeping everything super tidy but when I call callAPIMethod using the success/fail blocks it's locking up the UI/MainThread rather than being asynchronous as I'd expect.

我有一些问题。它工作并保持一切都非常整洁但是当我使用成功/失败块调用callAPIMethod时它会锁定UI / MainThread,而不是像我期望的那样异步。

How should I go about implementing this pattern? Or is there a better way to go about it?

我该如何实施这种模式?或者有更好的方法吗?

I don't need to support pre-iOS7.

我不需要支持iOS7之前的版本。

Thanks

谢谢

Edit: Basic implementation discussed above.

编辑:上面讨论的基本实现。

- (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 method, used as follows (from a UITableViewController):

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];
                     }];

1 个解决方案

#1


0  

Your NSURLSession code looks fine. I'd suggest adding some breakpoints so you can identify if it is deadlocking somewhere and if so, where. But nothing in this code sample would suggest any such problem.

您的NSURLSession代码看起来很好。我建议添加一些断点,以便你可以确定它是否在某处死锁,如果是,那么在哪里。但是,此代码示例中没有任何内容会暗示任何此类问题

I would suggest that you ensure that all UI calls are dispatched back to the main queue. This NSURLSessionUploadTask completion handler may be called on a background queue, but all UI updates (alerts, navigation, updating of UIView controls, etc.) must take place on the main queue.

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

#1


0  

Your NSURLSession code looks fine. I'd suggest adding some breakpoints so you can identify if it is deadlocking somewhere and if so, where. But nothing in this code sample would suggest any such problem.

您的NSURLSession代码看起来很好。我建议添加一些断点,以便你可以确定它是否在某处死锁,如果是,那么在哪里。但是,此代码示例中没有任何内容会暗示任何此类问题

I would suggest that you ensure that all UI calls are dispatched back to the main queue. This NSURLSessionUploadTask completion handler may be called on a background queue, but all UI updates (alerts, navigation, updating of UIView controls, etc.) must take place on the main queue.

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