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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。