iOS: 如何以最简单的方式测试互联网连接,而不冻结应用程序(没有可达性)?

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

在我的代码中,我曾经使用三种方式来检查互联网,但它们都有限制:

1/可达性方法:

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

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

限制:在大多数情况下都有效,但我的问题是,如果我在没有互联网的情况下连接天线 Wi-Fi,它说连接正常,但事实并非如此。这不是一个好的解决方案,我需要检查 Reachability 上似乎不可用的状态代码。

2/发送同步请求:

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

限制:它也有效,但我的问题是,如果超时,这种情况随时可能发生,它会在太多时间内冻结应用程序。如果我把它放在一个线程中,似乎当我在 dispatch_async 中发出请求时,没有考虑到响应。

3/发送异步请求:

    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!");
         }
     }];

限制:我认为这是更好的方法,但我的问题是我必须在我的代码中的每个地方都写,这将是一个污染。请问有没有比较轻便的方法呢

你怎么看?有没有另一种更容易检查互联网是否正常工作而不冻结应用程序的方法?

提前致谢。

另一种选择

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

Nayem 是对的 - 您应该将第三个选项(异步网络检查)包装在 class 方法中,如下所示:

+ (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!");
     }
 }];
}

然后像这样调用方法:

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