欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

判断设备是否真正的连接互联网

程序员文章站 2022-07-13 14:22:25
...

在iOS中监测网络状态有好几种方式,详情点击这里。但是在一般的网络监测都只是能够监测本地的网络状态,而真实的网络可达性不能监测到。比如:

  • 手机连接了wifi,但是wifi没有连接网络
  • 本地网络连接存在,但信号很差,实际无法连接到服务器
  • wifi需要认证,我们虽然没有认证,但是已经连接了本地网络

苹果Reachability代码demo说明中也告诉了我们这个事实
"Reachability cannot tell your application if you can connect to a particular host, only that an interface is available that might allow a connection, and whether that interface is the WWAN."
大概意思就是:如果你连接到了一个特定的主机地址,Reachability不能告诉你的应用连接的接口是可用的,无论是一个连接,还是是wifi。(英语不好,见谅)
同样的经常用到的网络第三方库AFNetworking也是是能监测到本地网络的状态。感兴趣的可以自己写代码测试下。
我的测试代码如下

- (void)viewDidLoad {
    [super viewDidLoad];

    NSURL *URL = [NSURL URLWithString:@"https://www.google.co.jp/webhp?hl=zh-CN"];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (response == nil) {
            NSLog(@"没有网络");
        }
        else{
            NSLog(@"网络是通的");
        }
    }];
    
    [dataTask resume];

    [self checkNetwork];
    
}


- (BOOL)checkNetwork {
    __block BOOL result;
    AppDelegate *app = (AppDelegate *)[UIApplication sharedApplication].delegate;
    UIWindow *window = app.window;
    
    AFNetworkReachabilityManager *ReachabilityManager = [AFNetworkReachabilityManager sharedManager];
    [ReachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:window animated:YES];
        result = status;
        switch (status) {
            case AFNetworkReachabilityStatusNotReachable:
                // 弹框提示的内容
                hud.labelText = @"当前网络不可用,请检查网络设置";
                break;
            case AFNetworkReachabilityStatusReachableViaWWAN:
                hud.labelText = @"2G/3G/4G";
                break;
            case AFNetworkReachabilityStatusReachableViaWiFi:
                hud.labelText = @"WiFi在线";
            default:
                break;
        }
        
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            // 显示时间1s
            sleep(5.);
            dispatch_async(dispatch_get_main_queue(), ^{
                // 让弹框消失
                [MBProgressHUD hideHUDForView:window animated:YES];
            });
        });
    }];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkStateChange) name:AFNetworkingReachabilityDidChangeNotification object:nil];
    [ReachabilityManager startMonitoring];
    return result;
}

- (void)networkStateChange{
    AFNetworkReachabilityManager *ReachabilityManager = [AFNetworkReachabilityManager sharedManager];
    //[ReachabilityManager startMonitoring];
    NSLog(@"manager.isReachable === %d++++++", ReachabilityManager.reachable);

}

针对这种情况,我的解决办法。虽然low点,笨点,关键是能用。

    // url地址最好写自己app要访问的地址,不能保证百度的服务器不抽筋,????
    NSURL *URL = [NSURL URLWithString:@"https://www.baidu.com"];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (response == nil) {
            NSLog(@"没有网络");
        }
        else{
            NSLog(@"网络是通的");
        }
    }];
    
    [dataTask resume];

同时在github上找到了别人针对Reachability封装的第三方RealReachability 。基本上其接口与方法和Reachability非常相似,上手容易,可以无缝对接。地址在这里