因為iOS的系統(tǒng)是封閉的,所以是沒有直接的APi去獲取當(dāng)前的網(wǎng)絡(luò)狀態(tài)。但是道高一尺痛单,魔高一尺。開發(fā)者總會有辦法獲取自己想要的東西劲腿。
1.一般設(shè)備下的網(wǎng)絡(luò)狀態(tài)獲取
獲取當(dāng)前的網(wǎng)絡(luò)類型
獲取當(dāng)前的網(wǎng)絡(luò)類型是通過獲取狀態(tài)欄旭绒,然后遍歷狀態(tài)欄的視圖完成的。
先導(dǎo)入頭文件,如下:
#import"AppDelegate.h"
實現(xiàn)方法如下:
+?(NSString?*)getNetworkType
{
????UIApplication?*app?=?[UIApplication?sharedApplication];
????NSArray?*subviews?=?[[[app?valueForKeyPath:@"statusBar"]?valueForKeyPath:@"foregroundView"]?subviews];
????NSString?*network?=?@"";
????for(id?subview?insubviews)?{
????????if([subview?isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")])?{
????????????intnetworkType?=?[[subview?valueForKeyPath:@"dataNetworkType"]?intValue];
????????????switch(networkType)?{
????????????????case0:
????????????????????network?=?@"NONE";
????????????????????break;
????????????????case1:
????????????????????network?=?@"2G";
????????????????????break;
????????????????case2:
????????????????????network?=?@"3G";
????????????????????break;
????????????????case3:
????????????????????network?=?@"4G";
????????????????????break;
????????????????case5:
????????????????????network?=?@"WIFI";
????????????????????break;
????????????????default:
????????????????????break;
????????????}
????????}
????}
????if([network?isEqualToString:@""])?{
????????network?=?@"NO?DISPLAY";
????}
????returnnetwork;
}
獲取當(dāng)前的Wifi信息
獲取當(dāng)前的Wifi信息需要借助系統(tǒng)的SystemConfiguration這個庫快压。
先導(dǎo)入頭文件,如下:
1#import
實現(xiàn)方法如下:
#pragma?mark?獲取Wifi信息
+?(id)fetchSSIDInfo
{
????NSArray?*ifs?=?(__bridge_transfer?id)CNCopySupportedInterfaces();
????id?info?=?nil;
????for(NSString?*ifnam?inifs)?{
????????info?=?(__bridge_transfer?id)CNCopyCurrentNetworkInfo((__bridge?CFStringRef)ifnam);
????????if(info?&&?[info?count])?{
????????????break;
????????}
????}
????returninfo;
}
#pragma?mark?獲取WIFI名字
+?(NSString?*)getWifiSSID
{
????return(NSString?*)[self?fetchSSIDInfo][@"SSID"];
}
#pragma?mark?獲取WIFI的MAC地址
+?(NSString?*)getWifiBSSID
{
????return(NSString?*)[self?fetchSSIDInfo][@"BSSID"];
}
獲取當(dāng)前的Wifi信號強(qiáng)度
獲取信號強(qiáng)度與獲取網(wǎng)絡(luò)狀態(tài)有點類似垃瞧,通過遍歷狀態(tài)欄蔫劣,從而獲取WIFI圖標(biāo)的信號強(qiáng)度。在獲取前需注意當(dāng)前狀態(tài)是否為WIFI个从。如下:
+?(int)getWifiSignalStrength{
????intsignalStrength?=?0;
//????判斷類型是否為WIFI
????if([[self?getNetworkType]isEqualToString:@"WIFI"])?{
????UIApplication?*app?=?[UIApplication?sharedApplication];
????id?statusBar?=?[app?valueForKey:@"statusBar"];
????UIView?*foregroundView?=?[statusBar?valueForKey:@"foregroundView"];
????NSArray?*subviews?=?[foregroundView?subviews];
????NSString?*dataNetworkItemView?=?nil;
????for(id?subview?insubviews)?{
????????if([subview?isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView")?class]])?{
????????????dataNetworkItemView?=?subview;
????????????break;
????????}
????}
????intsignalStrength?=?[[dataNetworkItemView?valueForKey:@"_wifiStrengthBars"]?intValue];
????}
????returnsignalStrength;
}
2.iPhone X下的網(wǎng)絡(luò)狀態(tài)獲取
在iPhone X下,小編尋找資料脉幢,找了一圈都沒有發(fā)現(xiàn)可以使小編滿意的答案,只找到了一個開源類Reachability嗦锐,這個類可以獲取iPhone X下的網(wǎng)絡(luò)狀態(tài)嫌松,當(dāng)然普通設(shè)備也可以用。但是在之后奕污,小編根據(jù)結(jié)構(gòu)萎羔,一步步尋找,終于找到自己想要的東西碳默。
Reachability的使用
下載開源類Reachability贾陷,然后根據(jù)文檔使用即可(該類把移動網(wǎng)絡(luò)統(tǒng)稱為WWAN):
+?(NSString?*)getNetworkTypeByReachability
{
????NSString?*network?=?@"";
????switch([[Reachability?reachabilityForInternetConnection]currentReachabilityStatus])?{
????????caseNotReachable:
????????????network?=?@"NONE";
????????????break;
????????caseReachableViaWiFi:
????????????network?=?@"WIFI";
????????????break;
????????caseReachableViaWWAN:
????????????network?=?@"WWAN";
????????????break;
????????default:
????????????break;
????}
????if([network?isEqualToString:@""])?{
????????network?=?@"NO?DISPLAY";
????}
????returnnetwork;
}
通過結(jié)構(gòu)獲取網(wǎng)絡(luò)類型
在研究這部分之前,小編在想嘱根,為什么在其他設(shè)備可以通過遍歷狀態(tài)欄發(fā)現(xiàn)網(wǎng)絡(luò)狀態(tài)髓废,但是在iPhone X不行。通過打斷點一步步摸索發(fā)現(xiàn)该抒,iPhone X的狀態(tài)欄的結(jié)果和其他設(shè)備不太一樣慌洪。在分級上復(fù)雜了許多,而且移動網(wǎng)絡(luò)和WIFI竟然是調(diào)用了兩個完全不太的類凑保。如下:
這讓小編感覺到了冈爹。。愉适。(自行腦補(bǔ))犯助,在不斷的探索下,終于完成了在上面的基礎(chǔ)適配iPhone X的網(wǎng)絡(luò)類型獲取维咸。
首先剂买,通過添加宏判斷是否是iPhone X,如下:
#define?KIsiPhoneX?([UIScreen?instancesRespondToSelector:@selector(currentMode)]???CGSizeEqualToSize(CGSizeMake(1125,?2436),?[[UIScreen?mainScreen]?currentMode].size)?:?NO)
然后通過層級結(jié)構(gòu)判斷類型,如下:
+?(NSString?*)getNetworkType
{
????UIApplication?*app?=?[UIApplication?sharedApplication];
????id?statusBar?=?[app?valueForKeyPath:@"statusBar"];
????NSString?*network?=?@"";
????if(KIsiPhoneX)?{
//????????iPhone?X
????????id?statusBarView?=?[statusBar?valueForKeyPath:@"statusBar"];
????????UIView?*foregroundView?=?[statusBarView?valueForKeyPath:@"foregroundView"];
????????NSArray?*subviews?=?[[foregroundView?subviews][2]?subviews];
????????for(id?subview?insubviews)?{
????????????if([subview?isKindOfClass:NSClassFromString(@"_UIStatusBarWifiSignalView")])?{
????????????????network?=?@"WIFI";
????????????}elseif([subview?isKindOfClass:NSClassFromString(@"_UIStatusBarStringView")])?{
????????????????network?=?[subview?valueForKeyPath:@"originalText"];
????????????}
????????}
????}else{
//????????非?iPhone?X
????????UIView?*foregroundView?=?[statusBar?valueForKeyPath:@"foregroundView"];
????????NSArray?*subviews?=?[foregroundView?subviews];
????????for(id?subview?insubviews)?{
????????????if([subview?isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")])?{
????????????????intnetworkType?=?[[subview?valueForKeyPath:@"dataNetworkType"]?intValue];
????????????????switch(networkType)?{
????????????????????case0:
????????????????????????network?=?@"NONE";
????????????????????????break;
????????????????????case1:
????????????????????????network?=?@"2G";
????????????????????????break;
????????????????????case2:
????????????????????????network?=?@"3G";
????????????????????????break;
????????????????????case3:
????????????????????????network?=?@"4G";
????????????????????????break;
????????????????????case5:
????????????????????????network?=?@"WIFI";
????????????????????????break;
????????????????????default:
????????????????????????break;
????????????????}
????????????}
????????}
????}
????if([network?isEqualToString:@""])?{
????????network?=?@"NO?DISPLAY";
????}
????returnnetwork;
}
通過結(jié)構(gòu)獲取WIFI信號強(qiáng)度
因為上面獲取SSID和BSSID的方法在iPhone X依然可用癌蓖,因此就不多加說明了瞬哼,獲取iPhone X信號強(qiáng)度的方法也類似于上方獲取類型。首先判斷是否屬于WIFI網(wǎng)絡(luò)租副,然后根據(jù)iPhone X特有的結(jié)構(gòu)找到特定的地方獲取值就行坐慰,如下:
#pragma?mark?獲取Wifi信號強(qiáng)度
+?(int)getWifiSignalStrength{
????intsignalStrength?=?0;
//????判斷類型是否為WIFI
????if([[self?getNetworkType]isEqualToString:@"WIFI"])?{
????????UIApplication?*app?=?[UIApplication?sharedApplication];
????????id?statusBar?=?[app?valueForKey:@"statusBar"];
????????if(KIsiPhoneX)?{
//????????????iPhone?X
????????????id?statusBarView?=?[statusBar?valueForKeyPath:@"statusBar"];
????????????UIView?*foregroundView?=?[statusBarView?valueForKeyPath:@"foregroundView"];
????????????NSArray?*subviews?=?[[foregroundView?subviews][2]?subviews];
????????????for(id?subview?insubviews)?{
????????????????if([subview?isKindOfClass:NSClassFromString(@"_UIStatusBarWifiSignalView")])?{
????????????????????signalStrength?=?[[subview?valueForKey:@"_numberOfActiveBars"]?intValue];
????????????????}
????????????}
????????}else{
//????????????非?iPhone?X
????????????UIView?*foregroundView?=?[statusBar?valueForKey:@"foregroundView"];
????????????NSArray?*subviews?=?[foregroundView?subviews];
????????????NSString?*dataNetworkItemView?=?nil;
????????????for(id?subview?insubviews)?{
????????????????if([subview?isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView")?class]])?{
????????????????????dataNetworkItemView?=?subview;
????????????????????break;
????????????????}
????????????}
????????????signalStrength?=?[[dataNetworkItemView?valueForKey:@"_wifiStrengthBars"]?intValue];
????????}
????}
????returnsignalStrength;
}