2014-04-06 2 views
0

API에 대한 모든 호출을 관리하는 클래스가 있습니다. 그것은이를 관리하는 방법을 가지고,이 방법은 successfail 블록을 받아이 callAPIMethod:NSURLSession uploadTaskWithRequest - 완료 핸들러 내에서 블록 사용

를 호출 할 수 있습니다.

이 메서드에서는 uploadTaskWithRequest을 호출하여 API를 호출합니다. uploadTaskWithRequest 완료 핸들러 내에서 결과에 따라 success 또는 fail 블록으로 결과를 전달하고 싶습니다.

여기에 몇 가지 문제가 있습니다. 그것은 작동하고 모든 슈퍼 깔끔한 유지하지만 성공/실패 블록을 사용하여 callAPIMethod 호출 할 때 그것은 UI/MainThread 내가 예상했던 것처럼 비동기되는 대신 잠금 것입니다.

이 패턴을 구현하려면 어떻게해야합니까? 아니면 그것에 대해 더 좋은 방법이 있습니까?

iOS 이전 버전을 지원할 필요가 없습니다.

감사합니다.

편집 : 위에서 설명한 기본 구현. (가있는 UITableViewController에서) 다음과 같이 사용

- (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 방법에있어서,

[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

메인 스레드로 디스패치 할 때 좋은 점. 성공시 새로운 뷰 컨트롤러를 nav 스택으로 푸시합니다. 내가 메인 스레드로도 파견해야한다고 생각하십니까? 'displayErrorMessage'는 에러 여부에 관계없이 UI가 잠겨 있어도 alertView를 보여줍니다. – avalore

+0

감사! 내가 생각하기에, 어리석은 실수. 나는 주 스레가 아니라면 추락했을 것이라고 추측했다. 단지 10 초 이상 걸리지 않았다. – avalore

답변

0

귀하의 NSURLSession 코드가 잘 보인다. 일부 중단 점을 추가하면 어딘가에 교착 상태가 있는지 여부를 식별 할 수 있고, 그렇다면 어디에서 확인할 수 있습니다. 그러나이 코드 샘플의 어떤 것도 그러한 문제를 암시하지 않습니다.

모든 UI 호출이 기본 대기열로 다시 전달되도록하는 것이 좋습니다. 이 NSURLSessionUploadTask 완료 핸들러는 백그라운드 대기열에서 호출 될 수 있지만 모든 UI 업데이트 (경고, 탐색, UIView 컨트롤 업데이트 등)는 기본 대기열에서 수행되어야합니다.