2014-04-06 55 views
0

我有一個類,它管理所有的api調用。 它來管理這個方法,讓我們稱這種callAPIMethod:NSURLSession uploadTaskWithRequest - 在完成處理程序中使用塊

此方法接受successfail塊。

在這個方法中,我打電話給uploadTaskWithRequest來調用一個API。 在uploadTaskWithRequest完成處理程序中,我希望(取決於結果)將結果傳遞迴successfail塊。

我有這個問題。它的工作原理是保持一切超級整潔,但當我使用成功/失敗塊調用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]; 
        }]; 
+0

編輯添加代碼。認爲這是一個可以接受的方式,因此可能做一些完全愚蠢的事情。 – avalore

+0

調度到主線程的好處。成功時,我將新的視圖控制器推送到導航堆棧。猜測我應該派遣到主線程呢? 'displayErrorMessage'顯示一個alertView,儘管UI是否被鎖定是否有錯誤。 – avalore

+0

謝謝!正如我想的那樣,一個愚蠢的錯誤。我以爲它會崩潰,如果不是在主線程上......而不是掛在10秒以上。 – avalore

回答

0

NSURLSession代碼看起來細。我建議添加一些斷點,以便確定它是否在某處死鎖,如果是,在哪裏。但是這個代碼示例中沒有任何內容會提示這樣的問題。

我建議您確保將所有UI調用分派回主隊列。這個NSURLSessionUploadTask完成處理程序可能會在後臺隊列上調用,但所有UI更新(警報,導航,更新UIView控件等)都必須在主隊列上進行。

相關問題