2012-04-24 5 views
0

방금 ​​최근에 ASIHttpRequest 라이브러리에서 AFNetworking으로 전환했습니다. 나는 단순함을 정말 좋아하지만, 여전히 비동기 코드를 구조화하는 방법을 이해하기 위해 고심하고있다.컨트롤러에 비동기 네트워킹 코드 구성

이 가입 고려하십시오.

  • 먼저 입력 된 이메일 주소가 사용 가능한지 확인하고 싶습니다.
  • 다음 입력 한 사용자 이름이 사용 가능한지 확인하고 싶습니다.
  • 위의 내용이 모두 유효하고 사용 가능한 경우 실제 가입 신청서를 제출하고 싶습니다.

내 코드는 다음과 같습니다.

- (void)signUp{ 

    BOOL hasValidEmail = [self validateEmail:email]; 
    BOOL hasValidUsername = [self validateUsername:username]; 

    if(!hasValidEmail){ 
     NSLog(@"Invalid email"); 
     return; 
    } 

    if(!hasValidUsername){ 
     NSLog(@"Invalid username"); 
     return; 
    } 

    if (hasValidEmail && hasValidUsername) { 
     NSLog(@"Go ahead and create account"); 
    } 
} 

네트워킹 방법의 비동기 특성을 고려하여 구조화하는 방법을 잘 모르겠습니다. 이전의 두 가지 가용성 검사가 응답을 받기 전에 마지막 상태에 도달하는 경우가 많습니다.

가능 여부 확인 방법과 같이 보일 것이다 : 어쩌면

- (BOOL)validateEmail:(NSString*)email{ 

    __block NSString* emailAlreadyExists = @""; 

    NSString* url = [NSString stringWithFormat:@"user/emailexists/%@", email]; 

    [[APIClient sharedClient] getPath:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { 

     emailAlreadyExists = [responseObject valueForKey:@"exists"]; 

    } failure:^(AFHTTPRequestOperation *operation, NSError* error) { 
     NSLog(@"Email availability check failed: %@", error.localizedDescription); 
    }]; 

    if([emailAlreadyExists isEqualToString:@"true"]){ 
     return NO; 
    } 

    return YES; 
} 

가 개선 필요가 내 블록 기술을이다,하지만 난 정말 당신이이 같은 시나리오를 구성 할 방법을 듣고 싶습니다?

코드 샘플이 "좋음"이지만 실제로 알고있는 패턴이나 좋은 기술을 찾고 있습니다.

감사합니다.

답변

0

나는 일반적으로 이러한 것들을 단계로 분해하고 이전 단계가 성공하면 다음 단계를 시작합니다. 이 목적을 위해 블록을 전달하는 것이 좋습니다.

이 분명히 늘 컴파일, 그러나 희망은 당신이 수행하는 방법에 대한 몇 가지 아이디어를 제공 할 수 있습니다 : 스위치가 너무 오래 추한지고

typedef enum 
{ 
    SignupErrorNetworkError, 
    SignupErrorEmailAlreadyTaken, 
    SignupErrorUsernameAlreadyTaken, 
} SignupError; 

typedef enum 
{ 
    // These steps must be performed in this order. 
    SignupStepValidateEmail, 
    SignupStepValidateUsername, 
    SignupStepCreateAccount, 
} SignupStep; 

typedef void (^SignupSuccessBlock)(); 
typedef void (^SignupFailureBlock)(SignupError reason); 

// Call this to sign up. 
- (void)signupWithSuccess:(SignupSuccessBlock)success failure:(SignupFailureBlock)failure 
{ 
    // Start the first step of the process. 
    [self performSignupStep:SignupStepValidateEmail success:success failure:failure]; 
} 

// Internal method. Don't call this from outside. 
- (void)performSignupStep:(SignupStep)step success:(SignupSuccessBlock)success failure:(SignupFailureBlock)failure 
{ 
    switch (step) 
    { 
     case SignupStepValidateEmail: 
      [[APIClient sharedClient] getPath:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { 
       if ([responseObject valueForKey:@"exists"]) 
       { 
        if (failure) failure(SignupErrorEmailAlreadyTaken); 
        return;    } 
       } 
       // Start next async step in signup process. 
       [self performSignupStep:SignupStepValidateUsername success:success failure:failure]; 
      } failure:^(AFHTTPRequestOperation *operation, NSError* error) { 
       if (failure) failure(SignupErrorNetworkError); 
      }]; 
      break; 
     case SignupStepValidateUsername: 
      // Similar to the step above. Starts the create account step on success. 
      break;    
     case SignupStepCreateAccount: 
      // Similar to the step above. Call the success block when done. 
      break;    
    } 
} 

경우도 별도의 방법으로 단계를 확인하고 삭제할 수를 step-enum : 등으로 계속되는 validateEmailWithSuccess:failure

위의 예에서 프로세스의 상태 시스템 특성을 강조하고 싶습니다.

+0

이것은 정확히 내가 찾고있는 종류의 설정이었습니다. 실제로 나는 블록을 읽을 필요가있다. 고맙습니다. –

관련 문제