在項目中,為了好的用戶體驗凸舵,有些場景必須線判斷網(wǎng)絡(luò)狀態(tài)祖娘,然后才能決定改干嘛。比如視頻播放啊奄,需要線判斷是Wifi還是4G,Wifi直接播放掀潮,4G先提示用戶菇夸。獲取網(wǎng)絡(luò)狀態(tài)的方法大概有三種:
1. Reachability
這是蘋果的官方演示demo中使用到的方法,我們可以到蘋果官方文檔里下載Demo(點擊左上角Download Sample Code 即可下載)仪吧,然后把Demo里的Reachability.h和.m考到自己項目中庄新,并在Build Phases 的 Link Binary 添加SystemConfiguration.framework框架,然后在需要使用的地方導(dǎo)入Reachability頭文件
在 Reachability頭文件中我們可以看到無網(wǎng)絡(luò),wifi和蜂窩網(wǎng)三個網(wǎng)絡(luò)狀態(tài)的枚舉值择诈,如下:
typedef enum : NSInteger {
NotReachable = 0,
ReachableViaWiFi,
ReachableViaWWAN
} NetworkStatus;
(1)獲取網(wǎng)絡(luò)狀態(tài):
在iOS 7之前械蹋,當(dāng)用戶網(wǎng)絡(luò)為蜂窩網(wǎng)絡(luò)時,是沒法判斷3G羞芍、4G等網(wǎng)絡(luò)類型的哗戈,iOS 7 后是可以判斷的
-(NSString *)internetStatus {
Reachability *reachability = [Reachability reachabilityWithHostName:@"www.apple.com"];
NetworkStatus internetStatus = [reachability currentReachabilityStatus];
NSString *net = @"WIFI";
switch (internetStatus) {
case ReachableViaWiFi:
net = @"WIFI";
break;
case ReachableViaWWAN:
net = @"蜂窩數(shù)據(jù)";
//net = [self getNetType ]; //判斷具體類型
break;
case NotReachable:
net = @"當(dāng)前無網(wǎng)路連接";
default:
break;
}
return net;
}
(2)當(dāng)用戶為手機自帶網(wǎng)絡(luò)時,判斷具體網(wǎng)絡(luò)類型
這時可以使用系統(tǒng)自帶的API來判斷是2G荷科、3G還是4G唯咬,這就要使用到CTTelephonyNetworkInfo這類,記得在工程添加CoreTelephony.framework畏浆,并導(dǎo)入頭文件<CoreTelephony/CTCarrier.h>胆胰、<CoreTelephony/CTTelephonyNetworkInfo.h>
- (NSString *)getNetType
{
CTTelephonyNetworkInfo *info = [[CTTelephonyNetworkInfo alloc] init];
NSString *currentStatus = info.currentRadioAccessTechnology;
if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyGPRS"]) {
netconnType = @"GPRS";
}else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyEdge"]) {
netconnType = @"2.75G EDGE";
}else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyWCDMA"]){
netconnType = @"3G";
}else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyHSDPA"]){
netconnType = @"3.5G HSDPA";
}else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyHSUPA"]){
netconnType = @"3.5G HSUPA";
}else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyCDMA1x"]){
netconnType = @"2G";
}else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyCDMAEVDORev0"]){
netconnType = @"3G";
}else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyCDMAEVDORevA"]){
netconnType = @"3G";
}else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyCDMAEVDORevB"]){
netconnType = @"3G";
}else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyeHRPD"]){
netconnType = @"HRPD";
}else if ([currentStatus isEqualToString:@"CTRadioAccessTechnologyLTE"]){
netconnType = @"4G";
}
}
用此方法判斷的蜂窩網(wǎng)絡(luò)類型有如下類型:
CTRadioAccessTechnologyGPRS //介于2G和3G之間,也叫2.5G ,過度技術(shù)
CTRadioAccessTechnologyEdge //EDGE為GPRS到第三代移動通信的過渡刻获,EDGE俗稱2.75G
CTRadioAccessTechnologyWCDMA
CTRadioAccessTechnologyHSDPA //亦稱為3.5G(3?G)
CTRadioAccessTechnologyHSUPA //3G到4G的過度技術(shù)
CTRadioAccessTechnologyCDMA1x //3G
CTRadioAccessTechnologyCDMAEVDORev0 //3G標(biāo)準(zhǔn)
CTRadioAccessTechnologyCDMAEVDORevA
CTRadioAccessTechnologyCDMAEVDORevB
CTRadioAccessTechnologyeHRPD //電信使用的一種3G到4G的演進技術(shù)蜀涨, 3.75G
CTRadioAccessTechnologyLTE //接近4G
2. 通過系統(tǒng)statusBar判斷
這種方法在iPhone X 上可能引起奔潰,可能是蘋果修改了statusBar的keyPath蝎毡,所以拿到的東西為nil厚柳,導(dǎo)致崩潰
//獲取當(dāng)前網(wǎng)絡(luò)狀態(tài) (iPhone X 上可能引發(fā)崩潰)
+ (NSString *)networkingStatesFromStatebar {
// 狀態(tài)欄是由當(dāng)前app控制的,首先獲取當(dāng)前app
UIApplication *app = [UIApplication sharedApplication];
//iphone X 會在這里崩潰
NSArray *children = [[[app valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];
int type = 0;
for (id child in children) {
if ([child isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) {
type = [[child valueForKeyPath:@"dataNetworkType"] intValue];
}
}
NSString *stateString = @"wifi";
switch (type) {
case 0:
stateString = @"notReachable";
break;
case 1:
stateString = @"2G";
break;
case 2:
stateString = @"3G";
break;
case 3:
stateString = @"4G";
break;
case 4:
stateString = @"LTE";
break;
case 5:
stateString = @"wifi";
break;
default:
break;
}
return stateString;
}
3. 通過AFNetworking
此方法可以寫在AppDelegate中顶掉,每當(dāng)網(wǎng)絡(luò)狀態(tài)發(fā)生變化時草娜,就可以發(fā)通知,實時監(jiān)測網(wǎng)絡(luò)變化痒筒,然后做相應(yīng)的處理
#pragma mark - ------------- 監(jiān)測網(wǎng)絡(luò)狀態(tài) -------------
- (void)monitorNetworking
{
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
switch (status) {
case -1:
NSLog(@"未知網(wǎng)絡(luò)");
break;
case 0:
NSLog(@"網(wǎng)絡(luò)不可達(dá)");
break;
case 1:
{
NSLog(@"GPRS網(wǎng)絡(luò)");
//發(fā)通知宰闰,帶頭搞事
[[NSNotificationCenter defaultCenter] postNotificationName:@"monitorNetworking" object:@"1" userInfo:nil];
}
break;
case 2:
{
NSLog(@"wifi網(wǎng)絡(luò)");
//發(fā)通知,搞事情
[[NSNotificationCenter defaultCenter] postNotificationName:@"monitorNetworking" object:@"2" userInfo:nil];
}
break;
default:
break;
}
if (status == AFNetworkReachabilityStatusReachableViaWWAN || status == AFNetworkReachabilityStatusReachableViaWiFi) {
NSLog(@"有網(wǎng)");
}else{
NSLog(@"沒網(wǎng)");
}
}];
}