2014-12-15 2 views
0

첫 번째보기 컨트롤러에서 원격 서비스에 로그인해야하는 응용 프로그램을 개발 중입니다. 사용자 이름과 암호를 삽입하기위한 UI를 만듭니다. 나는 다음과 같은 체크하기 버튼 로그인을 누르면 는 :우선 순위 실행 방법 iOS

  • 을 필드가 간단한 빈하지 않은 경우 내 버튼에서
  • 가 전에, 내부 뷰 컨트롤러에 SEGUE를 시작하면 내가 확인 내게 내부보기 컨트롤러를 보여줍니다. 사용자가 로그인 할 수 있는지 확인해야하는 메소드를 추가했습니다.

    - (BOOL)loginSuccessWith:(NSString*)userName and:(NSString*)password { 
        ConnectionHandler *connectionHandler = [[ConnectionHandler alloc]init]; 
        if ([connectionHandler startConnectionToServer:@"serverAddress" andUsername:userName withPassword:password andInstallationId:[[NSUserDefaults standardUserDefaults] objectForKey:@"instId"]]) { 
         return YES; 
        } else { 
         return NO; 
        } 
    
    } 
    

    당신이 경우에서 볼 수 있듯이 : 추적이 방법에서는 내가 사용자

에게 외부 클래스를 호출하는 방법을 인증하기 위해 서버에 접속을 할 수있는 외부 클래스를 호출입니다 사용자가 로그인 할 수있는 경우 메소드는 YES 또는 NO를 리턴합니다. ConnectionHandler 클래스에서 나는 다음과 같은 코드를 작성 :

#import "ConnectionHandler.h" 

@interface ConnectionHandler() { 
    BOOL authenticated; 
} 
@end 

@implementation ConnectionHandler 

- (BOOL)startConnectionToServer:(NSString *)address andUsername:(NSString *)username withPassword:(NSString *)password andInstallationId:(NSString*) installationId { 
    if (![self sendRequestToURL:address withMethod:@"POST" withUsername:username withPassword:password andInstallationId: installationId]) { 
     NSLog(@"Impossibile connettersi"); 
     return NO; 
    } else { 
     if (authenticated) { 
      return YES; 
     } else { 
      return NO; 
     } 
    } 
} 

- (id)sendRequestToURL:(NSString *)url withMethod:(NSString *)method withUsername:(NSString*)username withPassword:(NSString*)password andInstallationId:(NSString*)installationId { 
    NSURL *finalURL = [[NSURL alloc]init]; 

    if ([method isEqualToString:@"POST"]) { 
     finalURL = [NSURL URLWithString:url]; 
    } else { 
     NSLog(@"Metodo no previsto"); 
    } 

    NSString *post = [NSString stringWithFormat:@"username=%@&password=%@&installationId=%@", username, password, installationId]; 
    NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding]; 

    NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)postData.length]; 

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init]; 
    [request setURL:finalURL]; 
    [request setHTTPMethod:method]; 
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; 
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; 
    [request setHTTPBody:postData]; 

    NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self]; 
    if (connection) { 
     [connection start]; 
    } 
    return connection; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
    self.responseData = [[NSMutableData alloc]init]; 

} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    [self.responseData appendData:data]; 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    // Parsing della risposta dal server parlare con Giancarlo per vedere che tipo di risposta ottengo 
    NSDictionary *json; 
    NSError *err; 

    json = [NSJSONSerialization JSONObjectWithData:self.responseData options:NSJSONReadingMutableLeaves error:&err]; 
    if (err) { 
     UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"AT Brain" message:@"Impossibile satbilire una connessione con il server" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil]; 
     [alert show]; 
    } else { 
     NSString *error_code = [NSString stringWithFormat:@"%@", [json objectForKey:@"error_code"]]; 
     int success = [[json objectForKey:@"success"] intValue]; 
     NSString *error_desc = [NSString stringWithFormat:@"%@", [json objectForKey:@"error_desc"]]; 

     if ([self autenthicationOkWithErrorCode:error_code withSuccess:success andErrorDesc:error_desc]) { 
      authenticated = YES; 
     } else { 
      authenticated = NO; 
     } 
    } 
} 

- (BOOL)autenthicationOkWithErrorCode:(NSString*)error_code withSuccess:(int)success andErrorDesc:(NSString*)error_desc { 

    int errCode = [error_code intValue]; 

    if (success == 1) { 
     return YES; 
    } else if (success == 0) { 
     if (errCode == 2) { 
      UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"AT Brain" message:@"Controlla di aver inserito username, password e di avere un installationId" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil]; 
      [alert show]; 
      return NO; 
     } 
     if (errCode == 3) { 
      UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"AT Brain" message:@"Credenziali non valide, inserisci username e password corrette" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil]; 
      [alert show]; 
      return NO; 
     } 
     if (errCode == 4) { 
      UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"AT Brain" message:@"Utente non autorizzato ad accedere al servizio" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil]; 
      [alert show]; 
      return NO; 
     } 
     if (errCode == 5) { 
      UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"AT Brain" message:@"L'utenza a cui stai cercando di accedere è già associata ad un utente diverso" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil]; 
      [alert show]; 
      return NO; 
     } 
     if (errCode == 6) { 
      UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"AT Brain" message:@"Installation ID errato" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"OK", nil]; 
      [alert show]; 
      return NO; 
     } 
    } 
    return NO; 
} 

나는 문제없이 서버에 연결할 수 있지만 - (void)connectionDidFinishLoading:(NSURLConnection *)connection가 호출되기 전에 그것은 - (BOOL)startConnectionToServer:(NSString *)address andUsername:(NSString *)username withPassword:(NSString *)password andInstallationId:(NSString*) installationId에 모든 코드를 실행하고가에 NO 그래서 SEGUE를 반환 -(BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender 메서드가 NO를 반환하기 때문에 로그인보기 컨트롤러가 작동하지 않습니다. 그래서 내 문제는 방법의 실행을 기다리는 것입니다 - (void)connectionDidFinishLoading:(NSURLConnection *)connection- (BOOL)startConnectionToServer:(NSString *)address andUsername:(NSString *)username withPassword:(NSString *)password andInstallationId:(NSString*) installationId 메서드에서 else 섹션을 실행하기 전에 끝났습니까? 내 문제를 이해하시기 바랍니다. 문제 해결을 도와 주시면 감사하겠습니다.

답변

4

NSURLConnection은 비동기입니다. 당신은 그것을 걷어 차고 즉시 돌아옵니다. 완료되면 콜백을받습니다 (예 : connectionDidFinishLoading). 그것이 성공을 확인하고 다음 단계로 넘어갈 수있는 지점입니다.

주 스레드에서 loginSuccessWith:and:이 호출된다고 가정합니다 (이것은 매우 이상한 메서드 이름이며, 아마도 loginWithUsername:password:을 의미합니다). 따라서 완료하는 데 시간이 오래 걸릴 수있는 네트워크 요청 대기를 차단할 수 없습니다. 당신은 전체 UI를 건다.

URL Loading System Programming Guide에는이를 디자인하는 방법에 대한 많은 정보가 있습니다. 먼저 NSURLSession을보고 필요에 맞지 않으면 하위 레벨 NSURLConnection을 사용하십시오. NSURLSession을 사용하면 작업이 완료 될 때마다 실행될 완료 블록을 전달할 수 있습니다.

+2

실패한 경우'connection : didFailWithError :'도 처리하는 것을 잊지 마십시오. –