5G will have to wait for apple API updates, but that will be the process in the future.

As for judging the current network environment is 2G/3G/4G, I have often seen this problem before. Recently, I saw the API for judging the current network environment in a project. In the course of audio and video calls with WebRTC, I saw SCNetworkReachability in the Demo. When the network environment changes, I can judge what network environment is currently connected. The writing method is not good (because it is placed in the same class with other WebRTC logic). In fact, we just need to improve the official Reachability.

How to determine the current network environment

We can use # import < CoreTelephony/CTTelephonyNetworkInfo. H > under the framework of some API to determine the current network.

Let’s take a look at some constant definitions under the framework:

CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyGPRS          __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyEdge          __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyWCDMA         __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyHSDPA         __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyHSUPA         __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyCDMA1x        __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyCDMAEVDORev0  __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyCDMAEVDORevA  __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyCDMAEVDORevB  __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyeHRPD         __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
CORETELEPHONY_EXTERN NSString * const CTRadioAccessTechnologyLTE           __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
Copy the code

Isn’t this 2G/3G/4G network environment? I’m sure Apple will include a constant definition for 5G when it becomes ubiquitous.

A network environment judgment:

- (void)networkStatus
{
    NSArray *typeStrings2G = @[CTRadioAccessTechnologyEdge,
                               CTRadioAccessTechnologyGPRS,
                               CTRadioAccessTechnologyCDMA1x];
    
    NSArray *typeStrings3G = @[CTRadioAccessTechnologyHSDPA,
                               CTRadioAccessTechnologyWCDMA,
                               CTRadioAccessTechnologyHSUPA,
                               CTRadioAccessTechnologyCDMAEVDORev0,
                               CTRadioAccessTechnologyCDMAEVDORevA,
                               CTRadioAccessTechnologyCDMAEVDORevB,
                               CTRadioAccessTechnologyeHRPD];
    
    NSArray *typeStrings4G = @[CTRadioAccessTechnologyLTE];
    
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {CTTelephonyNetworkInfo *teleInfo= [[CTTelephonyNetworkInfo alloc] init]; NSString *accessString = teleInfo.currentRadioAccessTechnology;if ([typeStrings4G containsObject:accessString]) {
            NSLog(@"4 g");
        } else if ([typeStrings3G containsObject:accessString]) {
            NSLog(@"3 g");
        } else if ([typeStrings2G containsObject:accessString]) {
            NSLog(@"2 g network." ");
        } else {
            NSLog(@"Unknown network"); }}else {
        NSLog(@"Unknown network"); }}Copy the code

In the code after currentRadioAccessTechnology is iOS 7 new API.

Improve the Reachability

In iOS applications, the use scenario is definitely not active acquisition, should be when the network changes, automatic notification and so on, and then do some corresponding processing. Below, we will masturbate a Reachability on our own and then show the current network environment.

As we all know, when using Reachability, a notification will be given if the network changes, but we only have WiFi/WWAN/NotReach for the network state. We can make the network judgment above in the notification returned by Reachability under WWAN type. But it is better to put judgment in Reachability and return different network states directly when using it. Since the latest Reachability has supported IPV6, I have also made some improvements on the latest Reachability.

For the most part, like Reachability, I extended the enumeration type and modified the network state judgment.

The main changes are as follows:

typedef NS_ENUM(NSUInteger, HLNetWorkStatus) {
    HLNetWorkStatusNotReachable = 0,
    HLNetWorkStatusUnknown = 1,
    HLNetWorkStatusWWAN2G = 2,
    HLNetWorkStatusWWAN3G = 3,
    HLNetWorkStatusWWAN4G = 4,
    
    HLNetWorkStatusWiFi = 9,
};
Copy the code

Here is the modification of network type judgment:

- (HLNetWorkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags
{
    if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
    {
        // The target host is not reachable.
        return HLNetWorkStatusNotReachable;
    }
    
    HLNetWorkStatus returnValue = HLNetWorkStatusNotReachable;
    if((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0) { /* If the target host is reachable and no connection is  requiredthen we'll assume (for now) that you're on Wi-Fi... * /returnValue = HLNetWorkStatusWiFi;
    }
    
    if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
         (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
    {
        /*
         ... and the connection is on-demand (or on-traffic) ifthe calling application is using the CFSocketStream or higher APIs... * /if((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0) { /* ... and no [user] intervention is needed... * /returnValue = HLNetWorkStatusWiFi; }}if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
    {
        /*
         ... but WWAN connections are OK if the calling application is using the CFNetwork APIs.
         */
        NSArray *typeStrings2G = @[CTRadioAccessTechnologyEdge,
                           CTRadioAccessTechnologyGPRS,
                           CTRadioAccessTechnologyCDMA1x];
        
        NSArray *typeStrings3G = @[CTRadioAccessTechnologyHSDPA,
                           CTRadioAccessTechnologyWCDMA,
                           CTRadioAccessTechnologyHSUPA,
                           CTRadioAccessTechnologyCDMAEVDORev0,
                           CTRadioAccessTechnologyCDMAEVDORevA,
                           CTRadioAccessTechnologyCDMAEVDORevB,
                           CTRadioAccessTechnologyeHRPD];
        
        NSArray *typeStrings4G = @[CTRadioAccessTechnologyLTE];

        if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {CTTelephonyNetworkInfo *teleInfo= [[CTTelephonyNetworkInfo alloc] init]; NSString *accessString = teleInfo.currentRadioAccessTechnology;if ([typeStrings4G containsObject:accessString]) {
                return HLNetWorkStatusWWAN4G;
            } else if ([typeStrings3G containsObject:accessString]) {
                return HLNetWorkStatusWWAN3G;
            } else if ([typeStrings2G containsObject:accessString]) {
                return HLNetWorkStatusWWAN2G;
            } else {
                returnHLNetWorkStatusUnknown; }}else {
            returnHLNetWorkStatusUnknown; }}return returnValue;
}
Copy the code

The improved usage of Reachability

For ease of use, I will try to follow the practice of Reachability, so there is no big difference between the usage and the previous one, just a change of notice.

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:kNetWorkReachabilityChangedNotification object:nil];
    
    HLNetWorkReachability *reachability = [HLNetWorkReachability reachabilityWithHostName:@"www.baidu.com"]; self.hostReachability = reachability; [reachability startNotifier]; // notification processing - (void)reachabilityChanged:(NSNotification *)notification {HLNetWorkReachability *curReach = [notification object]; HLNetWorkStatus netStatus = [curReach currentReachabilityStatus]; switch (netStatus) {case HLNetWorkStatusNotReachable:
            NSLog(@"Network unavailable");
            break;
        case HLNetWorkStatusUnknown:
            NSLog(@"Unknown network");
            break;
        case HLNetWorkStatusWWAN2G:
            NSLog(@"2 g network." ");
            break;
        case HLNetWorkStatusWWAN3G:
            NSLog(@"3 g");
            break;
        case HLNetWorkStatusWWAN4G:
            NSLog(@"4 g");
            break;
        case HLNetWorkStatusWiFi:
            NSLog(@"WiFi");
            break;
            
        default:
            break; }}Copy the code

HLNetWorkReachability

Have Fun!