我正在开发一个应该登录到第一个视图控制器中的远程服务的应用程序我创建了一个用于插入用户名和密码的UI。 当我按下按钮登录时,我做了以下检查:
调用外部类的方法如下:
- (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
的执行?
我希望你理解我的问题,希望你能帮我解决,谢谢
答案 0 :(得分:4)
NSURLConnection
是异步的。你开始它,它立即返回。完成后会收到回调(例如connectionDidFinishLoading
)。这就是你可以检查成功并进入下一步的重点。
我假设在主线程上调用loginSuccessWith:and:
(这是一个非常奇怪的方法名称;你可能意味着loginWithUsername:password:
)。因此,它无法阻止等待可能需要很长时间才能完成的网络请求。你会挂起整个用户界面。
URL Loading System Programming Guide提供了大量有关如何设计此信息的信息。首先查看NSURLSession
,如果它不符合您的需求,请使用较低级NSURLConnection
。使用NSURLSession
,您可以传递将在操作完成时运行的完成块。