Create a GET request when a button is clicked

NSLog (@ "NO") and NSLog (@ "YES") are displayed instantly when pressed, all further code is executed only after ~ 40 seconds (output message from a received request, switching to another screen), and switching to another screen generally drops, enter image description here

- (IBAction)buttonConnect:(id)sender { NSURL *url = [NSURL URLWithString:lineURLresult]; // URL NSURLSessionDataTask *downloadTask = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { id object = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error]; if ([object isKindOfClass:[NSDictionary class]] && error == nil){ if([[object objectForKey:@"Success"] boolValue] == FALSE){ NSLog(@"NO"); _labelStatus.text = [object objectForKey:@"Message"]; } else { NSLog(@"True"); _labelStatus.text = @"YES"; // Переход на VievControllerTable ViewControllerTable *detail = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewControllerTable"]; [self.navigationController pushViewController:detail animated:YES]; } } }]; [downloadTask resume]; } 

There are no such problems with NSURLConnection.

 - (IBAction)buttonConnect:(id)sender { // создаем запрос NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:lineURLresult] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15.0]; // создаём соединение и начинаем загрузку NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; if (connection) { // соединение началось _labelStatus.text = @"Подключение..."; // создаем NSMutableData, чтобы сохранить полученные данные receivedData = [NSMutableData data]; } else { // при попытке соединиться произошла ошибка _labelStatus.text = @"Произошла ошибка!"; } } - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { // получен ответ от сервера [receivedData setLength:0]; } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { // добавляем новые данные к receivedData [receivedData appendData:data]; } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { // выводим сообщение об ошибке NSString *errorString = [[NSString alloc] initWithFormat:@"Ошибка подключения"]; _labelStatus.text = errorString; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { // Результат подключения NSError *error = nil; id object = [NSJSONSerialization JSONObjectWithData:receivedData options:NSJSONReadingAllowFragments error:&error]; if([[object objectForKey:@"Success"] boolValue] == FALSE) _labelStatus.text = [object objectForKey:@"Message"]; else { _labelStatus.text = @""; // Сохранение [[NSUserDefaults standardUserDefaults] setValue:self.lineNameProfile forKey:@"lineNameProfile"]; [[NSUserDefaults standardUserDefaults] setValue:self.linePassword forKey:@"linePassword"]; [[NSUserDefaults standardUserDefaults] synchronize]; // Переход на VievControllerTable ViewControllerTable *detail = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewControllerTable"]; [self.navigationController pushViewController:detail animated:YES]; } } 

    2 answers 2

    I can offer you several solutions to this problem:

    1) the completion handler must be in Main thread , for this you can use the sendAsynchronousRequest:queue:completionHandler: method

    2) You can use the AFNetworking library.

    Example:

     AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; [manager GET:yourURL parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { NSLog(@"SUCCESS"); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"Error: %@", error); }]; 

    3) The update UI should always be in main thread , otherwise the update may take about a minute. Put the code associated with the UI in a block:

     dispatch_async(dispatch_get_main_queue(), ^{ // обновление UI }); 

      I would advise using a different approach, I think this will solve the problem.

       NSURLSession *session = [NSURLSession sharedSession]; [[session dataTaskWithUrl:url completionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) { /* your code in callback (response) here */ }] resume]; 

      It is impossible to work with callback (completionHandler) in the main thread, since it will stop the operation of the application and will execute the code synchronously .

      Working with the UI (changing the text of the UITextField) should be asynchronous in the main thread, for this we use inside the completionHandler this:

       dispatch_async(dispatch_get_main_queue(), ^{ /* your UI updates here */ }); 

      In the end, we will have this story:

       [[session dataTaskWithUrl:url completionHandler:^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ _labelStatus.text = parsedString; }); }] resume];