iOS中如何判断当前网络环境是2G/3G/4G/5G/WiFi
前言
5G什么的,还得等苹果API更新啊,不过将来还是这个处理过程就是了。
关于判断当前的网络环境是2G/3G/4G,这个问题以前经常看到,最近在一工程里看到了如果判断的API。而在撸WebRTC音视频通话的时候,看到了Demo中将SCNetworkReachability与其结合,当网络环境改变时,判断当前连接的是什么网络环境,写法欠佳(因为将其与WebRTC的其他逻辑柔和在了一个类)。其实只需要将官方的Reachability做一下改进即可。
如何判断当前的网络环境
我们可以利用#import
先来看一下该框架下的一些常量定义:
CORETELEPHONY_EXTERNNSString*constCTRadioAccessTechnologyGPRS__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0); CORETELEPHONY_EXTERNNSString*constCTRadioAccessTechnologyEdge__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0); CORETELEPHONY_EXTERNNSString*constCTRadioAccessTechnologyWCDMA__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0); CORETELEPHONY_EXTERNNSString*constCTRadioAccessTechnologyHSDPA__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0); CORETELEPHONY_EXTERNNSString*constCTRadioAccessTechnologyHSUPA__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0); CORETELEPHONY_EXTERNNSString*constCTRadioAccessTechnologyCDMA1x__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0); CORETELEPHONY_EXTERNNSString*constCTRadioAccessTechnologyCDMAEVDORev0__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0); CORETELEPHONY_EXTERNNSString*constCTRadioAccessTechnologyCDMAEVDORevA__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0); CORETELEPHONY_EXTERNNSString*constCTRadioAccessTechnologyCDMAEVDORevB__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0); CORETELEPHONY_EXTERNNSString*constCTRadioAccessTechnologyeHRPD__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0); CORETELEPHONY_EXTERNNSString*constCTRadioAccessTechnologyLTE__OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_7_0);
这不就是2G/3G/4G等网络环境么?我想等5G普及之后,苹果肯定也会加入代表5G的常量定义的。
先看随手写的一个网络环境判断:
-(void)networkStatus { NSArray*typeStrings2G=@[CTRadioAccessTechnologyEdge, CTRadioAccessTechnologyGPRS, CTRadioAccessTechnologyCDMA1x]; NSArray*typeStrings3G=@[CTRadioAccessTechnologyHSDPA, CTRadioAccessTechnologyWCDMA, CTRadioAccessTechnologyHSUPA, CTRadioAccessTechnologyCDMAEVDORev0, CTRadioAccessTechnologyCDMAEVDORevA, CTRadioAccessTechnologyCDMAEVDORevB, CTRadioAccessTechnologyeHRPD]; NSArray*typeStrings4G=@[CTRadioAccessTechnologyLTE]; if([[[UIDevicecurrentDevice]systemVersion]floatValue]>=7.0){ CTTelephonyNetworkInfo*teleInfo=[[CTTelephonyNetworkInfoalloc]init]; NSString*accessString=teleInfo.currentRadioAccessTechnology; if([typeStrings4GcontainsObject:accessString]){ NSLog(@"4G网络"); }elseif([typeStrings3GcontainsObject:accessString]){ NSLog(@"3G网络"); }elseif([typeStrings2GcontainsObject:accessString]){ NSLog(@"2G网络"); }else{ NSLog(@"未知网络"); } }else{ NSLog(@"未知网络"); } }
代码中的currentRadioAccessTechnology是iOS7之后新加的API。
改进Reachability
在iOS应用中的使用场景肯定不是主动获取,应该是网络产生变化的时候,自动给出通知等,然后做一些相应的处理。下面我们就自己撸一个Reachability,然后给出当前的网络环境。
我们都知道,使用Reachability时,如果网络变化,会给出一个通知,但是我们获取的网络状态只有WiFi/WWAN/NotReach几种。我们可以在Reachability返回的通知里,WWAN这种类型下,再做上面的网络判断即可。但是更优的做法就将判断放在Reachability中,在使用的时候直接返回不同的网络状态。
由于最新的Reachability已经支持了IPV6,我也是在最新的Reachability上做了一些改进。
大部分方法跟Reachability一样,我扩展了枚举类型,修改了网络状态判断。
主要修改如下:
typedefNS_ENUM(NSUInteger,HLNetWorkStatus){ HLNetWorkStatusNotReachable=0, HLNetWorkStatusUnknown=1, HLNetWorkStatusWWAN2G=2, HLNetWorkStatusWWAN3G=3, HLNetWorkStatusWWAN4G=4, HLNetWorkStatusWiFi=9, };
这里是网络类型判断的修改:
-(HLNetWorkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags { if((flags&kSCNetworkReachabilityFlagsReachable)==0) { //Thetargethostisnotreachable. returnHLNetWorkStatusNotReachable; } HLNetWorkStatusreturnValue=HLNetWorkStatusNotReachable; if((flags&kSCNetworkReachabilityFlagsConnectionRequired)==0) { /* Ifthetargethostisreachableandnoconnectionisrequiredthenwe'llassume(fornow)thatyou'reonWi-Fi... */ returnValue=HLNetWorkStatusWiFi; } if((((flags&kSCNetworkReachabilityFlagsConnectionOnDemand)!=0)|| (flags&kSCNetworkReachabilityFlagsConnectionOnTraffic)!=0)) { /* ...andtheconnectionison-demand(oron-traffic)ifthecallingapplicationisusingtheCFSocketStreamorhigherAPIs... */ if((flags&kSCNetworkReachabilityFlagsInterventionRequired)==0) { /* ...andno[user]interventionisneeded... */ returnValue=HLNetWorkStatusWiFi; } } if((flags&kSCNetworkReachabilityFlagsIsWWAN)==kSCNetworkReachabilityFlagsIsWWAN) { /* ...butWWANconnectionsareOKifthecallingapplicationisusingtheCFNetworkAPIs. */ NSArray*typeStrings2G=@[CTRadioAccessTechnologyEdge, CTRadioAccessTechnologyGPRS, CTRadioAccessTechnologyCDMA1x]; NSArray*typeStrings3G=@[CTRadioAccessTechnologyHSDPA, CTRadioAccessTechnologyWCDMA, CTRadioAccessTechnologyHSUPA, CTRadioAccessTechnologyCDMAEVDORev0, CTRadioAccessTechnologyCDMAEVDORevA, CTRadioAccessTechnologyCDMAEVDORevB, CTRadioAccessTechnologyeHRPD]; NSArray*typeStrings4G=@[CTRadioAccessTechnologyLTE]; if([[[UIDevicecurrentDevice]systemVersion]floatValue]>=7.0){ CTTelephonyNetworkInfo*teleInfo=[[CTTelephonyNetworkInfoalloc]init]; NSString*accessString=teleInfo.currentRadioAccessTechnology; if([typeStrings4GcontainsObject:accessString]){ returnHLNetWorkStatusWWAN4G; }elseif([typeStrings3GcontainsObject:accessString]){ returnHLNetWorkStatusWWAN3G; }elseif([typeStrings2GcontainsObject:accessString]){ returnHLNetWorkStatusWWAN2G; }else{ returnHLNetWorkStatusUnknown; } }else{ returnHLNetWorkStatusUnknown; } } returnreturnValue; }
改进后的Reachability用法
为了便于使用,尽量按照Reachability的做法来处理,所以用法与之前没什么太大区别,就换了个通知而已。
[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(reachabilityChanged:)name:kNetWorkReachabilityChangedNotificationobject:nil]; HLNetWorkReachability*reachability=[HLNetWorkReachabilityreachabilityWithHostName:@"www.baidu.com"]; self.hostReachability=reachability; [reachabilitystartNotifier]; //通知处理 -(void)reachabilityChanged:(NSNotification*)notification { HLNetWorkReachability*curReach=[notificationobject]; HLNetWorkStatusnetStatus=[curReachcurrentReachabilityStatus]; switch(netStatus){ caseHLNetWorkStatusNotReachable: NSLog(@"网络不可用"); break; caseHLNetWorkStatusUnknown: NSLog(@"未知网络"); break; caseHLNetWorkStatusWWAN2G: NSLog(@"2G网络"); break; caseHLNetWorkStatusWWAN3G: NSLog(@"3G网络"); break; caseHLNetWorkStatusWWAN4G: NSLog(@"4G网络"); break; caseHLNetWorkStatusWiFi: NSLog(@"WiFi"); break; default: break; } }
完整Demo地址:HLNetWorkReachability (本地下载)。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。