目前我们获取手机网络类型主要还是用的 AFNetwork
但是AFNetwork有个问题就是类型不够充分,只能四种类型
typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
AFNetworkReachabilityStatusUnknown = -1,
AFNetworkReachabilityStatusNotReachable = 0,
AFNetworkReachabilityStatusReachableViaWWAN = 1,
AFNetworkReachabilityStatusReachableViaWiFi = 2,
};
- AFNetworkReachabilityStatusUnknown 未知网络
- AFNetworkReachabilityStatusNotReachable 无网络
- AFNetworkReachabilityStatusReachableViaWWAN 蜂窝移动网络
- AFNetworkReachabilityStatusReachableViaWiFi WIFI
具体获取代码如下
/**
监测网络类型
*/
-(void)configReachabilityStatusByAFNetwork {
AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
[manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
[MyAppConfigModel sharedSingleton].netWorkReachabilityStatus = status;
switch (status) {
case AFNetworkReachabilityStatusUnknown:
NSLog(@"⚠️⚠️⚠️⚠️⚠️⚠️⚠️当前网络:未知");
break;
case AFNetworkReachabilityStatusNotReachable:
NSLog(@"⚠️⚠️⚠️⚠️⚠️⚠️⚠️当前网络:网络无连接\n请检查网络");
break;
case AFNetworkReachabilityStatusReachableViaWWAN:
NSLog(@"⚠️⚠️⚠️⚠️⚠️⚠️⚠️当前网络:3G|4G");
break;
case AFNetworkReachabilityStatusReachableViaWiFi:
NSLog(@"⚠️⚠️⚠️⚠️⚠️⚠️⚠️当前网络:WiFi");
break;
default:
break;
}
}];
}
那么 如何获取蜂窝移动网络的具体类型呢?
这里就需要用到
#import <CoreTelephony/CoreTelephonyDefines.h>
#import <CoreTelephony/CTCarrier.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
具体代码如下
+ (NSInteger)getDeviceNetWorkingStatus{
NSString *state = [[NSString alloc] init];
NSInteger stateType = 0;
AFNetworkReachabilityStatus netWorkReachabilityStatus = [MyAppConfigModel sharedSingleton].netWorkReachabilityStatus;
switch (netWorkReachabilityStatus) {
case AFNetworkReachabilityStatusUnknown:
state = @"无网络";
stateType = 5;
break;
case AFNetworkReachabilityStatusNotReachable:
state = @"无网络";
stateType = 5;
break;
case AFNetworkReachabilityStatusReachableViaWWAN:
{
NSArray *typeStrings2G = @[CTRadioAccessTechnologyEdge,
CTRadioAccessTechnologyGPRS,
CTRadioAccessTechnologyCDMA1x];
NSArray *typeStrings3G = @[CTRadioAccessTechnologyHSDPA,
CTRadioAccessTechnologyWCDMA,
CTRadioAccessTechnologyHSUPA,
CTRadioAccessTechnologyCDMAEVDORev0,
CTRadioAccessTechnologyCDMAEVDORevA,
CTRadioAccessTechnologyCDMAEVDORevB,
CTRadioAccessTechnologyeHRPD];
NSArray *typeStrings4G = @[CTRadioAccessTechnologyLTE];
CTTelephonyNetworkInfo *teleInfo= [[CTTelephonyNetworkInfo alloc] init];
NSString *accessString = teleInfo.currentRadioAccessTechnology;
if ([typeStrings4G containsObject:accessString]) {
state = @"4G";
stateType = 2;
} else if ([typeStrings3G containsObject:accessString]) {
state = @"3G";
stateType = 3;
} else if ([typeStrings2G containsObject:accessString]) {
state = @"2G";
stateType = 4;
} else {
state = @"无网络";
stateType = 5;
}
}
break;
case AFNetworkReachabilityStatusReachableViaWiFi:
state = @"WIFI";
stateType = 1;
break;
default:
state = @"无网络";
stateType = 5;
break;
}
NSLog(@"当前网络网络状态 %@",state);
return stateType;
}
昨天在判断网络的发现发现xcode12竟然没有5G相关的key,今天升级到Xcode12.1发现多了CTRadioAccessTechnologyNRNSA和CTRadioAccessTechnologyNR。
NR是New Radio的缩写,新无线(5G)的意思,
NRNSA表示5G NR的非独立组网(NSA)模式
具体解释可看5G新无线
网络判断使用了Reachability
方式一:通过CoreTelephony获取网络状态
引入头文件
#import "Reachability.h"
#import <CoreTelephony/CTCarrier.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
开始网络判断:
+ (NSString *)networkStatus{
Reachability *reachability = [Reachability reachabilityWithHostName:@"www.apple.com"];
NetworkStatus internetStatus = [reachability currentReachabilityStatus];
NSString *net = @"WIFI";
switch (internetStatus) {
case ReachableViaWiFi:
net = @"WIFI";
break;
case ReachableViaWWAN:
net = [self getNetType]; //判断具体类型
break;
case NotReachable:
net = @"当前无网路连接";
default:
break;
}
NSLog(@"net is %@", net);
return net;
}
+ (NSString *)getNetType
{
CTTelephonyNetworkInfo *info = [[CTTelephonyNetworkInfo alloc] init];
/// 注意:没有SIM卡,值为空
NSString *currentStatus;
NSString *currentNet = @"5G";
if (@available(iOS 12.1, *)) {
if (info && [info respondsToSelector:@selector(serviceCurrentRadioAccessTechnology)]) {
NSDictionary *radioDic = [info serviceCurrentRadioAccessTechnology];
if (radioDic.allKeys.count) {
currentStatus = [radioDic objectForKey:radioDic.allKeys[0]];
}
}
}else{
currentStatus = info.currentRadioAccessTechnology;
}
if ([currentStatus isEqualToString:CTRadioAccessTechnologyGPRS]) {
currentNet = @"GPRS";
}else if ([currentStatus isEqualToString:CTRadioAccessTechnologyEdge]) {
currentNet = @"2.75G EDGE";
}else if ([currentStatus isEqualToString:CTRadioAccessTechnologyWCDMA]){
currentNet = @"3G";
}else if ([currentStatus isEqualToString:CTRadioAccessTechnologyHSDPA]){
currentNet = @"3.5G HSDPA";
}else if ([currentStatus isEqualToString:CTRadioAccessTechnologyHSUPA]){
currentNet = @"3.5G HSUPA";
}else if ([currentStatus isEqualToString:CTRadioAccessTechnologyCDMA1x]){
currentNet = @"2G";
}else if ([currentStatus isEqualToString:CTRadioAccessTechnologyCDMAEVDORev0]){
currentNet = @"3G";
}else if ([currentStatus isEqualToString:CTRadioAccessTechnologyCDMAEVDORevA]){
currentNet = @"3G";
}else if ([currentStatus isEqualToString:CTRadioAccessTechnologyCDMAEVDORevB]){
currentNet = @"3G";
}else if ([currentStatus isEqualToString:CTRadioAccessTechnologyeHRPD]){
currentNet = @"HRPD";
}else if ([currentStatus isEqualToString:CTRadioAccessTechnologyLTE]){
currentNet = @"4G";
}else if (@available(iOS 14.1, *)) {
if ([currentStatus isEqualToString:CTRadioAccessTechnologyNRNSA]){
currentNet = @"5G NSA";
}else if ([currentStatus isEqualToString:CTRadioAccessTechnologyNR]){
currentNet = @"5G";
}
}
return currentNet;
}
鉴于评论区反馈iOS14.0.1对5G判断产生的崩溃
,这里5G的判断从14.1
开始判断(独白:但是官方写着就是14.0
,真是个左右为难的问题~)
方式二:通过状态栏获取网络状态(不推荐)
因为私有属性在之后的版本会被取消,不推荐这种方式
- (NSString *)getNetStatusByStatusBar{
@try {
NSArray *children;
UIApplication *app = [UIApplication sharedApplication];
NSString *state;
// 全屏
if ([[app valueForKeyPath:@"_statusBar"] isKindOfClass:NSClassFromString(@"UIStatusBar_Modern")]) {
children = [[[[app valueForKeyPath:@"_statusBar"] valueForKeyPath:@"_statusBar"] valueForKeyPath:@"foregroundView"] subviews];
for (UIView *view in children) {
for (id child in view.subviews) {
//wifi
if ([child isKindOfClass:NSClassFromString(@"_UIStatusBarWifiSignalView")]) {
state = @"wifi";
}
//2G 3G 4G
if ([child isKindOfClass:NSClassFromString(@"_UIStatusBarStringView")]) {
if ([[child valueForKey:@"_originalText"] containsString:@"G"]) {
state = [child valueForKey:@"_originalText"];
}
}
}
}
}else {
children = [[[app valueForKeyPath:@"_statusBar"] valueForKeyPath:@"foregroundView"] subviews];
for (id child in children) {
if ([child isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {
//获取到状态栏
switch ([[child valueForKeyPath:@"dataNetworkType"] intValue]) {
case 0:
state = @"无网络";
//无网模式
break;
case 1:
state = @"2G";
break;
case 2:
state = @"3G";
break;
case 3:
state = @"4G";
break;
case 5:
state = @"wifi";
break;
default:
break;
}
}
}
}
return state;
}
@catch (NSException * __unused exception) {}
}
以下是项目中获取设备网络类型的代码:
//设备网络类型:Unknown=0; Wifi=1; 2G=2; 3G=3; 4G=4; 5G=5
-(NSInteger)connType{
NSString *state = [[NSString alloc] init];
NSInteger stateType = 0;
AFNetworkReachabilityStatus netWorkReachabilityStatus = [AFNetworkReachabilityManager sharedManager].networkReachabilityStatus;
switch (netWorkReachabilityStatus) {
case AFNetworkReachabilityStatusUnknown:
state = @"无网络";
stateType = 0;
break;
case AFNetworkReachabilityStatusNotReachable:
state = @"无网络";
stateType = 0;
break;
case AFNetworkReachabilityStatusReachableViaWWAN:
{
NSArray *typeStrings2G = @[CTRadioAccessTechnologyEdge,
CTRadioAccessTechnologyGPRS,
CTRadioAccessTechnologyCDMA1x];
NSArray *typeStrings3G = @[CTRadioAccessTechnologyHSDPA,
CTRadioAccessTechnologyWCDMA,
CTRadioAccessTechnologyHSUPA,
CTRadioAccessTechnologyCDMAEVDORev0,
CTRadioAccessTechnologyCDMAEVDORevA,
CTRadioAccessTechnologyCDMAEVDORevB,
CTRadioAccessTechnologyeHRPD];
NSArray *typeStrings4G = @[CTRadioAccessTechnologyLTE];
NSArray *typeStrings5G;
if (@available(iOS 14.1, *)) {
typeStrings5G = @[CTRadioAccessTechnologyNRNSA,CTRadioAccessTechnologyNR];
}
CTTelephonyNetworkInfo *teleInfo= [[CTTelephonyNetworkInfo alloc] init];
NSString *accessString = teleInfo.currentRadioAccessTechnology;
if (@available(iOS 14.1, *)) {
if ([typeStrings5G containsObject:accessString]) {
state = @"5G";
stateType = 5;
}
}
if ([typeStrings4G containsObject:accessString]) {
state = @"4G";
stateType = 4;
} else if ([typeStrings3G containsObject:accessString]) {
state = @"3G";
stateType = 3;
} else if ([typeStrings2G containsObject:accessString]) {
state = @"2G";
stateType = 2;
} else {
state = @"无网络";
stateType = 0;
}
}
break;
case AFNetworkReachabilityStatusReachableViaWiFi:
state = @"WIFI";
stateType = 1;
break;
default:
state = @"无网络";
stateType = 0;
break;
}
NSLog(@"当前网络网络状态 %@",state);
return stateType;
}