Search code examples
iosreachability

checking network reachability in real time


When the user presses a button, I need to know whether the device is connected to the internet at that very instant--not whether he was connected 3 seconds ago. The reachability (tonymillion) notifier takes about that long to update after there is a change in network reachability.

I thought that I would be able to check for actual access in real time using the following methods:

if (!([[Reachability reachabilityWithHostname:@"www.google.com"] currentReachabilityStatus] == NotReachable)) NSLog(@"reachable");
if ([[Reachability reachabilityWithHostname:@"www.google.com"] currentReachabilityStatus] == NotReachable) NSLog(@"not reachable");

But results indicated that in fact currentReachabilityStatus does not check for internet access; it only checks the same flag that is updated with ~3 seconds' delay.

What's an efficient way of actually checking for network access on the spot?


Solution

  • As you wished in the comments above here is a solution using a "HEAD" request.

    1. Make your class conforming to the NSURLConnectionDelegate.
    2. Implement the connection:didReceiveResponse: delegate method
    3. Optionally implement the connection:didFailWithError: delegate method

    So your setup could look like this:

    YourClass.m

    @interface YourClass () <NSURLConnectionDelegate>
    @property (strong, nonatomic) NSURLConnection *headerConnection;
    @end
    
    @implementation YourClass
    
    - (void)viewDidLoad {
        // You can do this in whatever method you want
        NSMutableURLRequest *headerRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com"] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:10.0];
        headerRequest.HTTPMethod = @"HEAD";
        self.headerConnection = [[NSURLConnection alloc] initWithRequest:headerRequest delegate:self];
    }
    
    #pragma mark - NSURLConnectionDelegate Methods
    
    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
        if (connection == self.headerConnection) {
            // Handle the case that you have Internet; if you receive a response you are definitely connected to the Internet
        }
    }
    
    - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
        // Note: Check the error using `error.localizedDescription` for getting the reason of failing
        NSLog(@"Failed: %@", error.localizedDescription);
    }