У меня есть приложение, которое выполняет асинхронную запись на сервер. Затем он декодирует json и возвращает сообщение с сервера. Я помещаю несколько записей журнала отладки в свой код, поэтому я знаю, что ответ с сервера, а также декодирование json мгновенно. Проблема заключается в том, что после того, как json будет декодирован, задача async запускается около 6 секунд, прежде чем она вызовет следующее событие (показ всплывающего диалогового окна).iOS async task freezes
- (IBAction)register:(id)sender {
[self startPost]; // Starts spinner animation
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self doPost]; // performs post
});
}
-(void)doPost
{
@try {
NSString *post =[[NSString alloc] initWithFormat:@"request=register&platform=ios&email=%@&password=%@",self.email.text,self.password.text];
//NSLog(@"PostData: %@",post);
NSURL *url=[NSURL URLWithString:@"https://site.com/api.php"];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];
//[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *response = nil;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
//NSLog(@"Response code: %d", [response statusCode]);
if ([response statusCode] >=200 && [response statusCode] <300)
{
NSString *responseData = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
//NSLog(@"Response ==> %@", responseData);
NSData *responseDataNew = [responseData dataUsingEncoding:NSUTF8StringEncoding];
NSError* error = nil;
NSDictionary *myDictionary = [NSJSONSerialization JSONObjectWithData:responseDataNew options:NSJSONReadingMutableContainers error:&error];
if (error){
[self alertStatus:@"Unknown response code from server" :@"Whoops!"];
NSLog(@"Response ==> %@", responseData);
[self postDone];
}else{
if ([myDictionary[@"error"] isEqualToNumber:(@1)])
{
NSLog(@"ERROR DETECTED");
[self alertStatus:myDictionary[@"message"]:@"Whoops!"];
[self postDone];
}
else
{
[self alertSuccess];
[self postDone];
}
}
} else {
if (error) NSLog(@"Error: %@", error);
[self alertStatus:@"Connection Failed" :@"Whoops!"];
[self postDone];
}
}
@catch (NSException * e) {
NSLog(@"Exception: %@", e);
[self alertStatus:@"Registration Failed." :@"Whoops!"];
[self postDone];
}
}
-(void)startPost
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
self.email.enabled = false;
self.password.enabled = false;
self.confirm.enabled = false;
self.cancelButton.enabled = false;
}
- (void) alertStatus:(NSString *)msg :(NSString *)title
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
message:msg
delegate:self
cancelButtonTitle:@"Ok"
otherButtonTitles:nil, nil];
[alertView setTag:0];
[alertView show];
}
- (void) alertSuccess
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Success!"
message:@"You have been successfully registered."
delegate:self
cancelButtonTitle:@"Ok"
otherButtonTitles:nil, nil];
[alertView setTag:1];
[alertView show];
}
-(void)postDone
{
self.registerButton.hidden = false;
self.spinner.hidden = true;
self.loadingText.hidden = true;
//[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
self.email.enabled = true;
self.password.enabled = true;
self.confirm.enabled = true;
self.cancelButton.enabled = true;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{if (alertView.tag == 1)
{
[self dismissViewControllerAnimated:YES completion:nil];
}}
Функции alertStatus и alertSuccess просто отображают окно сообщения ненадолго. Когда я запускаю код, я целенаправленно вводил плохую информацию, поэтому в журнале говорится: «ОШИБКА ОБНАРУЖЕНА». Проблема в том, что требуется еще 6 секунд, прежде чем что-нибудь случится после этого.
Вы не показываете метод postDone. Я предполагаю, что вы показываете представление предупреждения. Это нужно сделать на основной теме. – rmaddy
@rmaddy Я отредактировал исходное сообщение и добавил его в метод 'postDone'. – DarthCaniac
Вам нужно вызвать два метода «alert ...» в основном потоке. Это бесчисленное множество примеров. Найдите 'dispatch_async' и' dispatch_get_main_queue'. – rmaddy