2010-12-21 10 views
5

Mi aplicación de iPhone es bastante simple con una vista que maneja todo, en viewDidLoad miro para ver si tenemos una conexión a Internet y si lo hacemos cargamos desde la web y si no cargamos desde un recurso local. Y esto funciona bienEvento de cambio de red de accesibilidad que no se activa

//in viewDidOnload  
[[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(handleNetworkChange:) 
              name:kReachabilityChangedNotification object:nil]; 
reachability = [Reachability reachabilityForInternetConnection]; 
[reachability startNotifier]; 
NetworkStatus status = [reachability currentReachabilityStatus]; 

if (status == NotReachable) { 
    //Do something offline 
} else { 
    //Do sometihng on line 
} 

- (void)handleNetworkChange:(NSNotification *)notice{ 
NetworkStatus status = [reachability currentReachabilityStatus]; 
if (status == NotReachable) { 
    //Change to offline Message 
} else { 
    //Relaunch online application 
} 

} 

Para probar mi caso handleNetworkChange apagué todos los datos celulares pero dejó el wifi sucesivamente. Dentro del alcance del wifi, inicié la aplicación y todo funciona perfecto. Luego salgo del rango del wifi, pero mi handleNetworkChange nunca se dispara (probado usando uiAlertView). De pie fuera del alcance del wifi, mi aplicación lanza el mensaje fuera de línea sin problemas.

Mi sospecha es que se trata de un problema con el ciclo de vida del ViewController, ¿debería colocarse este código en la función de AppDelegate? Posiblemente ese sea un mejor diseño para comenzar.

+0

Creo que la línea NSNotification debe declararse DESPUÉS de que inicie la instancia de accesibilidad. – Raptor

Respuesta

18

Resulta que era un problema de gestión de la memoria, ya que no estaba conservando la variable de accesibilidad, por lo que tan pronto como saliera del alcance se llamaría al dealloc y eso llamaría al método stopNotifier. Por lo tanto, no hay actualizaciones ya que saldría del rango.

Así que en lugar de:

reachability = [Reachability reachabilityForInternetConnection]; 

hago

reachability = [[Reachability reachabilityForInternetConnection] retain]; 

y todo funciona!

Una cosa genial que aprendí con todo esto es que puedes simular una conexión perdida en el simulador simplemente apagando el aeropuerto. No más tener que pasear por afuera. :)

+0

¿Debo liberarlo en algún momento? Posiblemente en dealloc de mi viewcontroller? – ashansky

+0

Estoy usando ARC. me restringe el uso de retener.¿¿¿ahora que??? –

+1

En ese caso, debe mantener una referencia fuerte del objeto 'alcanzabilidad' en algún lugar (por ejemplo, como' propiedad @ @ de su clase ViewController) para retenerlo. – fatuhoku

0

Eche un vistazo al ejemplo de accesibilidad de Apple. Creo que comienzan sus notificaciones en AppDelegate. En una de mis aplicaciones, creé una variable booleana que se actualiza constantemente mediante el método de actualización de conectividad AppDelegate, así que en mis otros controladores de vista, solo necesito llamar al delegado y verificar el valor del bool IsConnected.

Solo para pensar en otra cosa ... He notado problemas con la clase de alcance en el que puede congelar tu aplicación cuando buscas una accesibilidad. En mis nuevas aplicaciones, omito por completo la clase de accesibilidad y en lugar de transmitir los métodos de delegado DidFail para NSUrlConnection y UIWebView para determinar si tengo conectividad verdadera. Ya no tengo que esperar a que la clase de accesibilidad lo descubra y no puedo decidir qué hacer, simplemente continúo con la llamada web y uso el local como un retroceso.

Espero que esto ayude !!

+0

hmm Debo estar haciendo algo muy mal. Intenté moverlo a AppDelegate y todavía nada ... – ashansky

-2

Su aplicación no se está ejecutando en segundo plano.

favor agregar este método en su clase delegada

- (void)applicationDidEnterBackground:(UIApplication *)application 
{ UIApplication* app = [UIApplication sharedApplication]; 

    UIBackgroundTaskIdentifier __block bgTask = [app beginBackgroundTaskWithExpirationHandler: ^{ 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [app endBackgroundTask:bgTask]; 
      bgTask = UIBackgroundTaskInvalid; 
     }); 
    }]; 

} 

Gracias

-1

Debe incluir systemconfiguration.framework a su proyecto.

Cuestiones relacionadas