How to detect loss of Internet access when a wifi source loses connection?

I am trying to get genuine internet connection status. I used Apple Reachability, but that only gave me Wi-Fi connection status, i.e. It did not cover the case when the device is connected via Wi-Fi (to a router or access point), but the Wi-Fi router or access point is not directly connected to the Internet. This scenario is played by pulling the Internet input cable from the Wi-Fi router. The achievement notification tool returns ReachableViaWiFi for reachabilityForInternetConnection and ReachabilityWithHostName . I am pretty good at this problem. I tried this with NSURLConnection , but I NSURLConnection out of battery too much and personally I didn’t like this solution to keep making URL requests, albeit in a background thread.

Here is the code I'm using (kindly provided by a SO companion, don't remember the exact link though)

  [[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]; 

then in the observer method:

  - (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; } } } 
+7
source share
3 answers

According to Reachability, it checks not only Wi-Fi, but also WWAN / 3G and lack of Internet access, why do you think it does not check, except for WIFI

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

if you want to check access to a specific host, you can set the host yourself

 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; } } 
+7
source

See Jordan Answer. There is a stupid mistake in Apple official information. The type for returnValue should be "NetworkStatus" instead of "BOOL":

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

Otherwise, you get the following terrible consequences:

  • Even if cellular is available, it will be presented as unavailable.
  • If Wi-Fi is not available, Wi-Fi will be displayed as available if a cellular connection is available.

I can’t believe that Apple never bothered to fix it.

(PS New to and lack of repetition to support Jordan)

+4
source

I also got the Wifi flag, even if it was disabled. There is an error in the Reachability.m method:

 - (NetworkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags 

it uses BOOL as the return value, but assigns it a structure value with three values:

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

So, if Wi-Fi or Cellular is available, it will be ReachableViaWiFi (since BOOL can be 0 or 1, but not two)

To fix this, simply change the method above this:

 BOOL returnValue = NotReachable; 

For this:

 int returnValue = NotReachable; 

And you are good to go. Hope this helps.

0
source

All Articles