2015-01-13 4 views
0

Эй У меня есть приложение я работаю, и часто я получаю следующее сообщение:Лучший способ справиться ошибки NSURLConnection - IPhone Разработка

NSURLConnection error: Error Domain=NSURLErrorDomain Code=-1005 
"The network connection was lost." 

Мой журнал будет регистрировать это и чем мое приложение будет замерзать. Я надеюсь, что мой лучший вариант просто отправить уведомление о том, что Интернет был утерян, и повторите попытку, а не закрытие моего приложения?

Вот что я делаю:

логины -> Основные нагрузки и контроллер работает следующим образом:

// EXECUTE SERVER CALL 
-(void)makeRequests 
{ 
    /* GRAB USERNAME TO BE SENT OVER FOR POPULATING DATA */ 
    NSArray *get = [[SSKeychain allAccounts] init]; 
    NSString *username = [get[0] objectForKey:@"acct"]; 
    NSDictionary *dictionary = @{@"function": @"populateHomePage", @"username" : username}; 
     NSError *error = nil; 
     NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error]; 
     NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
     if (error) 
     NSLog(@"%s: JSON encode error: %@", __FUNCTION__, error); 

     NSURL *url = [NSURL URLWithString:@"/IOS-Frame/grab-data.php"]; 
     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 

     [request setHTTPMethod:@"POST"]; 
     NSString *params = [NSString stringWithFormat:@"json=%@", 
         [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; 
     NSData *paramsData = [params dataUsingEncoding:NSUTF8StringEncoding]; 
     [request addValue:@"8bit" forHTTPHeaderField:@"Content-Transfer-Encoding"]; 
     [request addValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; 
     [request addValue:[NSString stringWithFormat:@"%lu", (unsigned long)[paramsData length]] forHTTPHeaderField:@"Content-Length"]; 
     [request setHTTPBody:paramsData]; 


     // issue the request 
     NSURLResponse *response = nil; 
     NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; 
     if (error) 
      NSLog(@"%s: NSURLConnection error: %@", __FUNCTION__, error); 

     NSString *responseString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding]; 
     NSLog(@"responseString: %@",responseString); 
     // GRAB STATUS OBJECT 
     NSDictionary* json = [NSJSONSerialization 
          JSONObjectWithData:returnData //1 

          options:kNilOptions 
          error:&error]; 
     self.dataGrabed_dictionary = [json objectForKey:@"retrieved_data"]; 
} 
+1

Вы используете свои веб-сервисы в главной теме? Это единственная причина, по которой я могу думать, что это заморозит ваше приложение. В общем, вы хотите сделать вызовы веб-сервисов на потоках фона, чтобы они не блокировали ваш пользовательский интерфейс во время выполнения. – Stonz2

+0

Hey @ stonz2 более конкретно Я запускаю веб-api из моего сервера, чтобы получить данные о загрузке основного файла вида. Итак, что происходит, пользователь регистрируется и отправляется в представление таблицы, которое заполняет данные из базы данных на моем веб-сервере. –

+0

Использует ли ваш «веб-api retrieve» использовать обратные вызовы делегатов веб-сервисов, такие как «connectionDidFinishLoading:» и «connection: didFailWithError:», и если да, правильно ли вы обрабатываете его при сбое соединения? Трудно догадаться, что может быть неправильным, когда вы предоставили такую ​​небольшую информацию о том, как работает ваше приложение. – Stonz2

ответ

1

Я бы обернул все после условия if(error) в операторе else (при отсутствии ответа на установку ответа/json, если служба не удалась). Это позволит убедиться, что вы не пытаетесь создать объекты с данными nil, которые могут вызвать проблемы. В вашем заявлении if, который улавливает ошибку, вы также можете воспользоваться этой возможностью, чтобы вызывающий метод знал, что служба не удалась.

Возможно, что вызывающий метод ожидает возвращения данных из этой службы. Если это не удастся, данные никогда не придут.

Непонятно, вызывается ли это в основном потоке или нет, поскольку метод вызова не отображается. При этом вы действительно хотите убедиться, что вы ударили веб-сервисы из фонового потока, чтобы ваш пользовательский интерфейс не зависал при его запуске. Я лично предпочитаю dispatch_async, но вы можете посмотреть разные способы отправки задач в фоновый поток.

+0

Эй, спасибо! У вас есть хорошие примеры метода, который вы предпочитаете. Также я вызываю метод в 'viewDidLoad' –

+0

. Вот ссылка на кого-то другого, спрашивающего о' dispatch_async' на SO: [Общие сведения о dispatch_async] (http://stackoverflow.com/questions/16283652/understanding-dispatch-async). более высокий голос показывает, где разместить код, который должен работать в фоновом режиме, а затем код, который будет выполнен в основном потоке (обновления пользовательского интерфейса и т. д.) после завершения фонового процесса. – Stonz2

2

Выполните этот ответ для internet connection test и просто заказать методы в очереди.

- (void)testInternetConnection 
{ 
    internetReachableFoo = [Reachability reachabilityWithHostname:@"www.google.com"]; 

    // Internet is reachable 
    internetReachableFoo.reachableBlock = ^(Reachability*reach) 
    { 
     // Update the UI on the main thread 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      NSLog(@"Yayyy, we have the interwebs!"); 

      //show activity indicator........block ui until data loads. 

      //queue methods 

      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
       // Save in the background 

       [self makerequests]; 

       dispatch_async(dispatch_get_main_queue(), ^{ 
        // Perform UI functions on the main thread! 
        //dismiss activity indicator 
       }); 
      }); 

     }); 
    }; 

    // Internet is not reachable 
    internetReachableFoo.unreachableBlock = ^(Reachability*reach) 
    { 
     // Update the UI on the main thread 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      NSLog(@"Someone broke the internet :("); 
      //show some alert.... 

     }); 
    }; 

    [internetReachableFoo startNotifier]; 
} 

P.S. Это намек, а не точный ответ.

+0

Даже если в начале вызова есть интернет-соединение, это не гарантирует, что соединение не будет потеряно. – Stonz2

+0

да! когда он теряет соединение, он уведомляет, но не блокирует ui правильно? @ Stonz2 – Avis

+0

Из того, что я могу сказать, это одноразовая проверка, чтобы убедиться, что есть подключение к Интернету, и если да, продолжайте и выполняйте все необходимое для подключения к Интернету соединение. Однако, если у вас есть соединение, инициируйте веб-службу, и пока все еще выполняется, ваше соединение прерывается, я не вижу, где этот код мог бы захватить это. – Stonz2

Смежные вопросы