iOS testing la conectividad con el server durante la aplicación Lanuching toma demasiado time

Tengo una aplicación que permite el inicio de session automático para un usuario. Lo que mi jefe quiere es que, cuando la aplicación se inicie, la aplicación deba probar la conectividad con nuestro server (no solo probar si hay WiFi o networking 3G). Tomé prestada la muestra de alcanzabilidad de Apple , funciona.

Un problema es que lleva demasiado time, especialmente en el momento del lanzamiento. Lo probé en una networking inalámbrica local sin connection a internet, me tomó casi medio minuto hacerlo. Y dado que el inicio de session automático llamó a -ViewDidLoad (), durante ese medio minuto, ui no se cargó. Simplemente no es aceptable tomarse el time tanto time. Lo que es peor, si mi aplicación tarda demasiado en cargarse, iOS incluso podría cerrar la aplicación.

Además, tengo muchas llamadas de service web en mi aplicación. Entiendo que cada llamada a un service web podría tener la posibilidad de fallar, porque la naturaleza que iPhone / iPad puede perder o get connection fácilmente, incluso cuando el usuario habla un corto paseo de un lugar a otro. Personalmente, no me gusta, pero eso es lo que mi jefe quiere que haga, y probablemente tenga que probar la connection con bastante frecuencia en la aplicación.

Así que aquí lo que estoy buscando es una forma de detectar la connection realmente muy rápido (en cuestión de segundos) o una forma de hacerlo detrás de escena y no afectar la experiencia del usuario.

¿Alguien tiene sugerencias?

Gracias por tomarte tu time leyendo mis preguntas.

Presente una vista de carga intermedia con presentModalViewController mientras se realiza la testing y ejecute la testing real utilizando performSelectorInBackground . Luego, regrese al hilo principal con performSelectorOnMainThread :

 - (void)viewDidLoad { [super viewDidLoad]; // Make this a hidden member loadingViewController = [LoadingViewController new]; [self presentModalViewController:loadingViewController animated:NO]; [self performSelectorInBackground:@selector(testConnectivity) withObject:nil]; } - (void)testConnectivity { // Do expensive testing stuff [self performSelectorOnMainThread:@selector(testCompleted) withObject:nil waitUntilDone:NO]; } - (void)testCompleted { [loadingViewController dismissViewControllerAnimated:YES]; loadingViewController = nil; } 

Tenga en count que la experiencia general del usuario de esperar 30 segundos para que la aplicación comience es una mierda, y la conectividad a menudo cambia mientras está usando una aplicación, por lo que incluso si realiza la testing cada inicio, es poco probable que sea confiable. Pero si es lo que quiere tu jefe sufro contigo. 😉

Por lo que vale, aquí está el método que uso ..

 - (BOOL)checkServerAvailability { bool success = false; const char *host_name = [@"host" cStringUsingEncoding:NSASCIIStringEncoding]; SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, host_name); SCNetworkReachabilityFlags flags; success = SCNetworkReachabilityGetFlags(reachability, &flags); bool isAvailable = success && (flags & kSCNetworkFlagsReachable) && !(flags & kSCNetworkFlagsConnectionRequinetworking); CFRelease(reachability); return isAvailable; } 

Aquí está el resultado de logging del método de verificación de mi server …

 2012-07-11 11:29:04.892 ASURecycles[1509:f803] starting server check... 2012-07-11 11:29:04.894 ASURecycles[1509:f803] creating reachability... 2012-07-11 11:29:04.894 ASURecycles[1509:f803] creating flags... 2012-07-11 11:29:04.913 ASURecycles[1509:f803] checking for success of reachability, assigning to flags.. 2012-07-11 11:29:04.913 ASURecycles[1509:f803] checking our flags to determine network status... 2012-07-11 11:29:04.913 ASURecycles[1509:f803] not available 

Como puede ver, fracciones de segundo. Por supuesto, nuestro server está experimentando problemas en este momento, pero creo que su problema puede ser un problema de server, no un problema de marco. Siempre podría intentar ejecutar la comprobación del server en otro hilo.

Como dije en los comentarios, deberías usar el enfoque de Hampus Nilsson para realizar la request en el background de todos modos.

Con respecto a su problema de 30 segundos, encontré esto en otro blog :

 - (BOOL)isHostAvailable:(NSString*)hostName { // this should check the host but does not work in the simulator, aka it returns YES when should be no SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName cStringUsingEncoding:NSASCIIStringEncoding]); SCNetworkReachabilityFlags flags; BOOL success = SCNetworkReachabilityGetFlags(reachability, &flags); if (reachability) { CFRelease(reachability); } if ( ( success && (flags & kSCNetworkFlagsReachable) && !(flags & kSCNetworkFlagsConnectionRequinetworking) ) == NO) { return NO; } // we know at least the network is up, second check for a known page NSData *dataReply; NSURLResponse *response; NSError *error; // create the request NSString *urlString = [NSString stringWithFormat:@"http://%@/index.php", hostName]; NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:urlString] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:8.0]; // Make the connection dataReply = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&response error:&error]; if (response != nil) { NSLog(@"SNNetworkController.isHostAvailable %@", response); return YES; } else { // inform the user that the download could not be made NSLog(@"SNNetworkController.isHostAvailable %@ %@", response, error); return NO; } } 

Esto realizará una request con un valor de time de espera de 8 segundos.

//EDITAR:
ASIHTTPRequest :

 ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url]; [request setNumberOfTimesToRetryOnTimeout:3]; [request setTimeOutSeconds:20.0]; [request setRequestMethod:@"POST"]; [request startAsynchronous];