iOS iOS方法的优先执行

时间:2014-12-15 14:56:39

标签: ios objective-c nsurlconnection

我正在开发一个应该登录到第一个视图控制器中的远程服务的应用程序我创建了一个用于插入用户名和密码的UI。 当我按下按钮登录时,我做了以下检查:

  • 我用简单的if
  • 检查字段是否为空
  • 从我的按钮启动一个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中的else部分之前等待方法- (BOOL)startConnectionToServer:(NSString *)address andUsername:(NSString *)username withPassword:(NSString *)password andInstallationId:(NSString*) installationId的执行? 我希望你理解我的问题,希望你能帮我解决,谢谢

1 个答案:

答案 0 :(得分:4)

NSURLConnection是异步的。你开始它,它立即返回。完成后会收到回调(例如connectionDidFinishLoading)。这就是你可以检查成功并进入下一步的重点。

我假设在主线程上调用loginSuccessWith:and:(这是一个非常奇怪的方法名称;你可能意味着loginWithUsername:password:)。因此,它无法阻止等待可能需要很长时间才能完成的网络请求。你会挂起整个用户界面。

URL Loading System Programming Guide提供了大量有关如何设计此信息的信息。首先查看NSURLSession,如果它不符合您的需求,请使用较低级NSURLConnection。使用NSURLSession,您可以传递将在操作完成时运行的完成块。