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

妖精的绣舞 提交于 2020-03-22 06:37:53

问题


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.


回答1:


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



回答2:


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


来源:https://stackoverflow.com/questions/48341595/ios-how-to-test-internet-connection-in-the-most-easy-way-without-freezing-the

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!