问题
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