2013-02-28 20 views
7

Sto cercando di ottenere l'autentico stato di connettività Internet. Ho usato la Raggiungibilità di Apple, ma mi sta solo fornendo lo stato della connettività Wi-Fi, ad esempio non coprendo il caso quando il dispositivo è connesso via wifi (a un router o hotspot), ma il router o hotspot wifi non è connesso a Internet. Questo scenario è riproducibile estraendo il cavo di input Internet dal router wifi. Il notificante della raggiungibilità restituisce ReachableViaWiFi sia per reachabilityForInternetConnection sia per ReachabilityWithHostName. Sono abbastanza in una correzione con questo problema. L'ho provato tramite lo NSURLConnection, ma questo sta scaricando troppo la batteria e personalmente non mi piace questa soluzione per continuare a fare richieste URL, anche se in un thread in background.Come rilevare la perdita di raggiungibilità di Internet quando la sorgente wifi perde la connessione?

Ecco il codice che sto usando (per gentile concessione di un SO compagni, non ricordo il link esatto però)

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil]; 

    internetReachable = [[Reachability reachabilityForInternetConnection] retain]; 
    [internetReachable startNotifier]; 

    // check if a pathway to a random host exists 
    hostReachable = [[Reachability reachabilityWithHostName: @"www.google.com"] retain]; 
    [hostReachable startNotifier]; 

poi nel metodo osservatore:

- (void) checkNetworkStatus:(NSNotification *)notice{ 

    // called after network status changes 

    NetworkStatus internetStatus = [internetReachable currentReachabilityStatus]; 
    switch (internetStatus) 

    { 
     case NotReachable: 
     { 
      NSLog(@"The internet is down."); 
      self.isInternetReachable = NO; 

      break; 

     } 
     case ReachableViaWiFi: 
     { 
      NSLog(@"The internet is working via WIFI."); 
      self.isInternetReachable = YES; 

      break; 

     } 
     case ReachableViaWWAN: 
     { 
      NSLog(@"The internet is working via WWAN."); 
      self.isInternetReachable = YES; 

      break; 

     } 
    } 
    NetworkStatus hostStatus = [hostReachable currentReachabilityStatus]; 
    switch (hostStatus) 

    { 
     case NotReachable: 
     { 
      NSLog(@"A gateway to the host server is down."); 
      self.isHostReachable = NO; 

      break; 

     } 
     case ReachableViaWiFi: 
     { 
      NSLog(@"A gateway to the host server is working via WIFI."); 
      self.isHostReachable = YES; 

      break; 

     } 
     case ReachableViaWWAN: 
     { 
      NSLog(@"A gateway to the host server is working via WWAN."); 
      self.isHostReachable = YES; 

      break; 

     } 
} 
} 
+1

Hi @Ahmed. Hai mai trovato una soluzione a questo? Ho lo stesso identico problema: i miei utenti hanno i propri dispositivi connessi a un hotspot Wi-Fi e quando l'hotspot perde la connettività, l'app non lo sa. –

+0

2016 e ancora è irrisolto, ha avuto lo stesso problema. –

risposta

7

Secondo Reachability controlla non solo la connessione wifi, ma anche per WWAN/3G e nessun accesso a Internet, perché pensi che non controlli altro che WIFI?

typedef enum { 

    NotReachable = 0, 

    ReachableViaWiFi, 

    ReachableViaWWAN 

} NetworkStatus; 

se si desidera controllare la raggiungibilità ad un particolare host allora si potrebbe impostare l'host da soli come questo

Reachability *hostReach = [Reachability reachabilityWithHostName: @"www.google.com"]; 

NetworkStatus netStatus = [hostReach currentReachabilityStatus]; 

switch (netStatus) 
    { 
     case ReachableViaWWAN: 
     { 
      NSLog(@"WWAN/3G"); 
      break; 
     } 
     case ReachableViaWiFi: 
     { 
      NSLog(@"WIFI"); 
      break; 
     } 
     case NotReachable: 
     { 
      NSLog(@"NO Internet"); 
      break; 
     } 
} 
+0

Sto facendo esattamente quello che hai dichiarato per la raggiungibilità dell'host ma alla fine ottengo ReachableViaWiFi ogni volta? – Ahmed

+0

perché potresti essere connesso a WIFI in quel momento, provare a disabilitare il Wi-Fi del tuo dispositivo e poi provare a vedere cosa ottieni per lo stato? – nsgulliver

+0

@Ahmed ha risolto il problema? è la prima volta che usi "Raggiungibilità"? – nsgulliver

0

mi stavo troppo la bandiera Wifi anche con scollegato. C'è un errore nel metodo Reachability.m:

- (NetworkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags 

utilizza un BOOL come valore di ritorno, ma assegna ad esso i valori di una struct con 3 valori:

typedef enum : NSInteger { 
    NotReachable = 0, 
    ReachableViaWiFi, 
    ReachableViaWWAN 
} NetworkStatus; 

Quindi, se se Wi-Fi o cellulare sono disponibili, lo farà ReachableViaWiFi (come BOOL può essere 0 o 1, ma non due)

Per risolvere il problema, basta cambiare nel metodo di sopra di questo:

BOOL returnValue = NotReachable; 

Per questo:

int returnValue = NotReachable; 

E tu sei a posto. Spero che sia d'aiuto.

+0

Ho cambiato il BOOL in 'NetworkStatus' (che è il tipo corretto) ma non funziona ancora per me. Ricevo ancora ReachableViaWiFi anche quando il WiFi è spento. – progrmr

4

Vedere la risposta di Jordan. C'è uno stupido bug nel Reachability ufficiale di Apple. Il tipo per returnValue dovrebbe essere "networkstatus" invece di "BOOL":

- (NetworkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags 
{ 
    ... 
    NetworkStatus returnValue = NotReachable; 
    ... 
} 

In caso contrario, si finisce con le seguenti conseguenze terribili:

  1. Anche se connessione cellulare è disponibile, sarà segnalato come non disponibile.
  2. Se il WiFi non è disponibile, il Wifi sarà segnalato come disponibile se la connessione cellulare è disponibile.

Non riesco a credere che Apple non si sia mai preoccupata di risolvere il problema.

(P.S. Nuovo per impilare troppo pieno e non hanno ripetizioni per upvote Giordania)

Problemi correlati