zoukankan      html  css  js  c++  java
  • iOS 判断网络连接状态之重写Reachability

      获取网络连接状态目前有多种方法,其他的都比较好理解,不过都有些局限性,利用statusBar的subViews的信息来获取网络状态是比较简明的,但是在隐藏状态栏的情况下失效,还有使用私有API的方法,这里我们谈谈怎么用Reachability实现判断当前网络状态,包含无连接/2G/3G/4G/wifi。

      首先了解下 网络连接标识 SCNetworkReachabilityFlags

      typedef CF_OPTIONS(uint32_t, SCNetworkReachabilityFlags) {

        kSCNetworkReachabilityFlagsTransientConnection = 1<<0,  // 可以通过瞬时连接(例如PPP---点对点通讯协议) 链接到给定的节点名和地址

        kSCNetworkReachabilityFlagsReachable = 1<<1,         // 当前网络配置可以请求到给定的节点名和地址

        kSCNetworkReachabilityFlagsConnectionRequired = 1<<2,  // 当前网络配置可以请求到给定的节点名和地址,但必须先创建一个连接。如果创建这个标识,需要象征性地生成kSCNetworkReachabilityFlagsConnectionOnTraffickSCNetworkReachabilityFlagsConnectionOnDemand, 或者 kSCNetworkReachabilityFlagsIsWWAN 等标识来指明需要创建的连接类型。如果用户需要手动创建连接,kSCNetworkReachabilityFlagsInterventionRequired标识也将被生成

        kSCNetworkReachabilityFlagsConnectionOnTraffic = 1<<3,  //当前网络配置可以请求到给定的节点名和地址,但必须先创建一个连接。定向到指定节点或地址的通信将发起该连接,该标识原来名为kSCNetworkReachabilityFlagsConnectionAutomatic

        kSCNetworkReachabilityFlagsInterventionRequired = 1<<4, //当前网络配置可以请求到给定的节点名和地址,但必须先创建一个连接
    用户需要通过某些方式的介入来创建该连接,比如提供密码、认证口令等。一般的,只有在一个拨号通信的配置中,在自动连接过程中发生某些错误(比如没有拨号音,没有回应,无效的密码等),这种情况下,PPP通信将会终止连接直到用户介入。

        kSCNetworkReachabilityFlagsConnectionOnDemand = 1<<5, //当前网络配置可以请求到给定的节点名和地址,但必须先创建一个连接。请求一经CFSocketStream程序接口请求就创建,其他的函数不会创建该连接

        kSCNetworkReachabilityFlagsIsLocalAddress = 1<<16,   // 所请求的节点或地址为连接到当前系统的网络节点  

        kSCNetworkReachabilityFlagsIsDirect = 1<<17,     // 网络通信不会通过网关连接给定的节点名和地址,而是直接路由到系统中的一个接口上。

      #if TARGET_OS_IPHONE

        kSCNetworkReachabilityFlagsIsWWAN = 1<<18,      // 可通过蜂窝数据网络访问给定的节点或地址

      #endif // TARGET_OS_IPHONE

        kSCNetworkReachabilityFlagsConnectionAutomatic = kSCNetworkReachabilityFlagsConnectionOnTraffic

      };

    然后就是通过这些标识来判断当前网络类型了。

    那么第一步就是获取这些标识

      SCNetworkReachabilityFlags flags;

        

        if (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags))

        {

            // 此处获得的flags即能指示当前网络环境的标识

        }

    再对flags进行分析判断,了解网络类型

        if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)

        {

       // 无法连接网络

        }    

        if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)

        {

            // 给定的节点或地址是可达的,并且不需要先请求一个多余的连接,那么我们可以判断是通过Wi-Fi连接的(不需要密码)

        }

        

        if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||

             (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))

        {

            // 通过CFSocketStream或者更高级的APIs发起on-demand (或者 on-traffic)请求

            if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)

            {

                // 不需要用户介入的情况下,我们判断为Wi-Fi

            }

        }

        if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)

        {

            /*

             通过CFNetwork APIs发起蜂窝数据网络请求

             */

            if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)

            {

                

          /*

                 蜂窝数据网络分2/3/4G,此处使用CTTelephonyNetworkInfo来判断,只适用于iOS 7及以上

               */

                CTTelephonyNetworkInfo * info = [[CTTelephonyNetworkInfo alloc] init];

                NSString *currentRadioAccessTechnology = info.currentRadioAccessTechnology;

                if (currentRadioAccessTechnology)

                {

                    if ([currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyLTE])

                    {

                        // 4G

                    }

                    else if ([currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyEdge] || [currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyGPRS] || [currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMA1x])

                    {

                        // 2G

                    }

                    else

                    {

                        // 3G

                    }

                }

            }

            if ((flags & kSCNetworkReachabilityFlagsTransientConnection) == kSCNetworkReachabilityFlagsTransientConnection)

            {

                if((flags & kSCNetworkReachabilityFlagsConnectionRequired) == kSCNetworkReachabilityFlagsConnectionRequired)

                {

                    // 2G

                }

                // 3G

            }

            // 由于flags标识中不能提供4G的具体标识,故走到这一步即可认为当前为4G网络环境

            // 4G

        }

  • 相关阅读:
    进度条
    打开文件的功能代码 JFileChooser
    我对JAVA的初认知
    集合之五:Set接口
    集合之四:List接口
    集合之三:泛型
    Maven web项目(简单的表单提交) 搭建(eclipse)
    集合之二:迭代器
    集合之一:集合概述
    java的函数
  • 原文地址:https://www.cnblogs.com/Jacue/p/5081706.html
Copyright © 2011-2022 走看看