iOS: How to test Internet connection in the most easy way, without freezing the app (without Reachability)?

786 Views Asked by At

In my code I used to use three ways for checking Internet, but there is limits to them:

1/ Reachability method:

- (BOOL)isInternetOk
{
    Reachability *curReach = [Reachability reachabilityWithHostName:@"apple.com"];
    NetworkStatus netStatus = [curReach currentReachabilityStatus];

    if (netStatus != NotReachable) //if internet connexion ok
    {
        return YES;
    }
    else
    {
        return NO;
    }
}

Limit: It works in the most case, but my problem is that if I connect an antenna Wi-Fi without no internet on it, it says that the connection is okay, and it is not true. It is not a good solution, I need to check the status code that it seems not available on Reachability.

2/sendSynchronousRequest:

- (BOOL)isInternetOk2
{
    NSMutableURLRequest* request = [[NSMutableURLRequest alloc] init];
    NSURL* URL = [NSURL URLWithString:@"https://www.google.com"];
    NSError *error = nil;

    [request setURL:URL];
    [request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
    [request setTimeoutInterval:15];

    NSData* response2 = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
    if (error)
    {
        return NO;
    }
    else
    {
        return YES;
    }
}

Limit: It works too, but my problem is that if there is a time out, that can happen at every moment, it freezes the app during too much time. If I put it in a thread, it seems that when I do a request in a dispatch_async, the response is not taking in account.

3/sendAsynchronousRequest:

    NSOperationQueue *myQueue = [[NSOperationQueue alloc] init];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.google.com"]];
    request.timeoutInterval = 10;

    [NSURLConnection sendAsynchronousRequest:request queue:myQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
     {
         NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
         NSLog(@"response status code: %ld, error status : %@", (long)[httpResponse statusCode], error.description);

         if ((long)[httpResponse statusCode] >= 200 && (long)[httpResponse statusCode]< 400)
         {
             // do stuff
             NSLog(@"Connected!");
         }
         else
         {
             NSLog(@"Not connected!");
         }
     }];

Limit: I think it is the better way to do, but my problem is that I have to write that every where in my code, which will be a polution. I wonder if there is a less heavy way to do it.

What do you think about it? Is there another way easier to check if internet is working without freezing the app?

Thanks in advance.

2

There are 2 best solutions below

1
Solsma Dev On BEST ANSWER

Nayem is right - you should wrap the third option (async network check) in a class method like this:

+ (void)checkInternetConnectivityWithSuccessCompletion:(void (^)(void))completion {

NSOperationQueue *myQueue = [[NSOperationQueue alloc] init];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.google.com"]];
request.timeoutInterval = 10;

[NSURLConnection sendAsynchronousRequest:request queue:myQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
 {
     NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
     NSLog(@"response status code: %ld, error status : %@", (long)[httpResponse statusCode], error.description);

     if ((long)[httpResponse statusCode] >= 200 && (long)[httpResponse statusCode]< 400)
     {
         // do stuff
         NSLog(@"Connected!");
         completion();
     }
     else
     {
         NSLog(@"Not connected!");
     }
 }];
}

And then call the method like this:

[YourClass checkInternetConnectivityWithSuccessCompletion:^{
    // your internet is working - add code here
}];
1
Shehata Gamal On

Another option with

#import <SystemConfiguration/SCNetworkReachability.h>

.....

+(bool)isNetworkAvailable {
    SCNetworkReachabilityFlags flags;
    SCNetworkReachabilityRef address;
    address = SCNetworkReachabilityCreateWithName(NULL, "www.apple.com");
    Boolean success = SCNetworkReachabilityGetFlags(address, &flags);
    CFRelease(address);
    bool canReach = success
    && !(flags & kSCNetworkReachabilityFlagsConnectionRequired)
    && (flags & kSCNetworkReachabilityFlagsReachable);
    return canReach;
}