美文网首页
判断当前网络状态 - iOS

判断当前网络状态 - iOS

作者: 你好哈喽哈喽 | 来源:发表于2020-08-19 11:49 被阅读0次

    在目前项目中,为了更好的用户体验,有些场景下首先需要进行当前网络状态的判断后,再执行后续流程。

    例如:下载、音频、视频的播放等相关的一些操作前,首先需要对当前用户网络环境进行判断,是 WiFi 还是 4G 等。

    WiFi则可以继续执行后续操作流程,如果当前网络处于 4G 的情况下,需要使用流量才可执行后续操作,则应提醒用户是否执行后续操作的提示,使得用户体验效果更佳。

    一般常用获取网络状态的方式如下:

    一、Reachability

    首先,苹果官方提供了演示的 demo 中所用到的方法(飞机票:ReachabilityDemo);

    其次,将 demo 中 Reachability 的类导入至工程,并在 Build Phases -> Link Binary 中添加 SystemConfiguration.framework 框架;

    最后,在需要使用的地方引入 Reachability 的头文件并调用类中所提供的接口方法即可。

    在 Reachability 头文件中可得知网络状态的枚举值,如下所示:

    typedef enum : NSInteger {
    
       NotReachable = 0,
    
       ReachableViaWiFi,
    
       ReachableViaWWAN
    
    } NetworkStatus
    
    

    获取网络状态方法一:

    #pragma mark - 获取当前网络状态
    
    /**
    
    *  获取当前网络状态
    
    *
    
    *  0:无网络 & 1:2G & 2:3G & 3:4G & 5:WIFI
    
    */
    
    - (NSInteger)getCurrentNetworkState {
    
       NSString *netWorkState = [[AFNetworkReachabilityManager sharedManager] localizedNetworkReachabilityStatusString];
    
       /*
    
        AFNetworkReachabilityStatusUnknown          = -1,
    
        AFNetworkReachabilityStatusNotReachable     = 0,
    
        AFNetworkReachabilityStatusReachableViaWWAN = 1,
    
        AFNetworkReachabilityStatusReachableViaWiFi = 2,
    
        */
    
       NSLog(@"NewWorkState --- %@", netWorkState);
    
       if ([netWorkState isEqualToString:@"Unknow"] || [netWorkState isEqualToString:@"Not Reachable"]) {// 未知 或 无网络
    
           return 0;
    
       }
    
       else if ([netWorkState isEqualToString:@"Reachable via WWAN"]) {// 蜂窝数据
    
           return 1;
    
       }
    
       else {// WiFi
    
           return 2;
    
       }
    
    }
    
    

    注:在 iOS7 之前,当用户网络为蜂窝网络时,无法判断 3G、4G 等网络类型,而在 iOS7 后则可以进行该项判断操作。

    方法二:

    - (NSString *)internetStatus {
    
       Reachability *reachability   = [Reachability reachabilityWithHostName:@"www.apple.com"];
    
       NetworkStatus internetStatus = [reachability currentReachabilityStatus];
    
       NSString *net = @"WIFI";
    
       switch (internetStatus) {
    
           case ReachableViaWiFi:
    
               net = @"WIFI";
    
               break;
    
           case ReachableViaWWAN:
    
               net = @"蜂窝数据";
    
    //            net = [self getNetType ];   //判断具体类型
    
               break;
    
           case NotReachable:
    
               net = @"当前无网路连接";
    
           default:
    
               break;
    
       }
    
       return net;
    
    }
    
    

    此时可以使用自带的 API 进行判断是 2G、3G、4G,但需要使用到CTTelephonyNetworkInfo 类。

    当用户手机为自带网络时,判断具体网络类型;

    首先,需要在工程中添加 CoreTelephony.framework 框架;

    其次,引入该类头文件。

    - (NSString *)getNetType {
    
       CTTelephonyNetworkInfo *info = [[CTTelephonyNetworkInfo alloc] init];
    
       NSString *currentStatus = info.currentRadioAccessTechnology;
    
       if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyGPRS"]) {
    
           netconnType = @"GPRS";
    
       }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyEdge"]) {
    
           netconnType = @"2.75G EDGE";
    
       }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyWCDMA"]){
    
           netconnType = @"3G";
    
       }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyHSDPA"]){
    
           netconnType = @"3.5G HSDPA";
    
       }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyHSUPA"]){
    
           netconnType = @"3.5G HSUPA";
    
       }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyCDMA1x"]){
    
           netconnType = @"2G";
    
       }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyCDMAEVDORev0"]){
    
           netconnType = @"3G";
    
       }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyCDMAEVDORevA"]){
    
           netconnType = @"3G";
    
       }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyCDMAEVDORevB"]){
    
           netconnType = @"3G";
    
       }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyeHRPD"]){
    
           netconnType = @"HRPD";
    
       }else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyLTE"]){
    
           netconnType = @"4G";
    
       }
    
    }
    
    

    使此方法判断蜂窝网络类型,如下

    CTRadioAccessTechnologyGPRS         //介于2G和3G之间,也叫2.5G ,过度技术
    
    CTRadioAccessTechnologyEdge         //EDGE为GPRS到第三代移动通信的过渡,EDGE俗称2.75G
    
    CTRadioAccessTechnologyWCDMA
    
    CTRadioAccessTechnologyHSDPA            //亦称为3.5G(3?G)
    
    CTRadioAccessTechnologyHSUPA            //3G到4G的过度技术
    
    CTRadioAccessTechnologyCDMA1x       //3G
    
    CTRadioAccessTechnologyCDMAEVDORev0    //3G标准
    
    CTRadioAccessTechnologyCDMAEVDORevA
    
    CTRadioAccessTechnologyCDMAEVDORevB
    
    CTRadioAccessTechnologyeHRPD        //电信使用的一种3G到4G的演进技术, 3.75G
    
    CTRadioAccessTechnologyLTE          //接近4G
    
    

    二、通过 statusBar 判断

    注:该方法在 iPhoneX 中运行程序会导致程序 crash!初步判断为苹果官方将 statusBar 的 keyPath 内参数变更所引起获取数据结果集为 nil,最终导致程序的 crash!坑啊!!!

    #pragma mark - 获取当前网络状态
    
    /**
    
    *  获取当前网络状态
    
    *
    
    *  0:无网络 & 1:2G & 2:3G & 3:4G & 5:WIFI
    
    */
    
    - (NSInteger)getCurrentNetworkState {  
    
       int type = 0;
    
       NSArray *children = [[[kApplication valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];
    
       for (id child in children) {
    
           if ([child isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {
    
               type = [[child valueForKeyPath:@"dataNetworkType"] intValue];
    
           }
    
       }
    
       return type;
    
    } 
    
    

    三、通过第三方 AFNetworking
    此方法通常使用在 AppDelegate 中,每当网络状态发生改变时便会发送当前变更状态,起到了实时监控当前网络状态变化的监控操作,有利于及时处理相关操作。

    #pragma mark - ****************************** 网络环境监听
    /**
     网络环境监听
    
     方法中基于 MBProgressHUD 的方法详见类方法中,GitHub 链接如下 
     (https://github.com/survivorsfyh/YHTools/blob/master/MBProgressHUD%2BYH.h)
     (https://github.com/survivorsfyh/YHTools/blob/master/MBProgressHUD%2BYH.m)
    
     */
    - (void)AFNReachability {
        // 创建网络监听管理者
        AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
        // 监听网络状态
        [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
            switch (status) {
                case AFNetworkReachabilityStatusUnknown:
                    NSLog(@"未知");
                    [MBProgressHUD showCommonHudWithAlertString:@"未知"
                                                     afterDelay:2.0
                                                         toView:self.window];
    
                    break;
                case AFNetworkReachabilityStatusNotReachable:
                    NSLog(@"暂无网络");
                    [MBProgressHUD showCommonHudWithAlertString:@"暂无网络"
                                                     afterDelay:2.0
                                                         toView:self.window];
    
                    break;
                case AFNetworkReachabilityStatusReachableViaWWAN:
                    NSLog(@"4G");
                    [MBProgressHUD showCommonHudWithAlertString:@"4G"
                                                     afterDelay:2.0
                                                         toView:self.window];
    
                    break;
                case AFNetworkReachabilityStatusReachableViaWiFi:
                    NSLog(@"WIFI");
                    [MBProgressHUD showCommonHudWithAlertString:@"WiFi"
                                                     afterDelay:2.0
                                                         toView:self.window];
    
                    break;
    
                default:
                    break;
            }
    
            if (status != AFNetworkReachabilityStatusNotReachable && !kStringIsEmpty([UserTableOperation getCurrentUserWithToken])) {// 有网了的情况下通知 bookShelf 检测 banner 是否存在
                [kNotificationCenter postNotificationName:@"NoticeBookShelfCheckBanner" object:nil];
            }
    
        }];
    
        // 开启监测
        [manager startMonitoring];
    }
    
    

    方法二请慎用,真的坑!

    相关文章

      网友评论

          本文标题:判断当前网络状态 - iOS

          本文链接:https://www.haomeiwen.com/subject/cyurjktx.html