iPhone X獲取設(shè)備的網(wǎng)絡(luò)狀態(tài)

因?yàn)閕OS的系統(tǒng)是封閉的,所以是沒(méi)有直接的APi去獲取當(dāng)前的網(wǎng)絡(luò)狀態(tài)。但是道高一尺,魔高一尺。開(kāi)發(fā)者總會(huì)有辦法獲取自己想要的東西。


1.一般設(shè)備下的網(wǎng)絡(luò)狀態(tài)獲取

獲取當(dāng)前的網(wǎng)絡(luò)類(lèi)型

獲取當(dāng)前的網(wǎng)絡(luò)類(lèi)型是通過(guò)獲取狀態(tài)欄,然后遍歷狀態(tài)欄的視圖完成的。

先導(dǎo)入頭文件,如下:

#import"AppDelegate.h"

實(shí)現(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這個(gè)庫(kù)。

先導(dǎo)入頭文件,如下:

1#import

實(shí)現(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信號(hào)強(qiáng)度

獲取信號(hào)強(qiáng)度與獲取網(wǎng)絡(luò)狀態(tài)有點(diǎn)類(lèi)似,通過(guò)遍歷狀態(tài)欄,從而獲取WIFI圖標(biāo)的信號(hào)強(qiáng)度。在獲取前需注意當(dāng)前狀態(tài)是否為WIFI。如下:

+?(int)getWifiSignalStrength{


????intsignalStrength?=?0;

//????判斷類(lèi)型是否為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下,小編尋找資料,找了一圈都沒(méi)有發(fā)現(xiàn)可以使小編滿意的答案,只找到了一個(gè)開(kāi)源類(lèi)Reachability,這個(gè)類(lèi)可以獲取iPhone X下的網(wǎng)絡(luò)狀態(tài),當(dāng)然普通設(shè)備也可以用。但是在之后,小編根據(jù)結(jié)構(gòu),一步步尋找,終于找到自己想要的東西。

Reachability的使用

下載開(kāi)源類(lèi)Reachability,然后根據(jù)文檔使用即可(該類(lèi)把移動(dòng)網(wǎng)絡(luò)統(tǒng)稱(chē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;

}

通過(guò)結(jié)構(gòu)獲取網(wǎng)絡(luò)類(lèi)型

在研究這部分之前,小編在想,為什么在其他設(shè)備可以通過(guò)遍歷狀態(tài)欄發(fā)現(xiàn)網(wǎng)絡(luò)狀態(tài),但是在iPhone X不行。通過(guò)打斷點(diǎn)一步步摸索發(fā)現(xiàn),iPhone X的狀態(tài)欄的結(jié)果和其他設(shè)備不太一樣。在分級(jí)上復(fù)雜了許多,而且移動(dòng)網(wǎng)絡(luò)和WIFI竟然是調(diào)用了兩個(gè)完全不太的類(lèi)。如下:


這讓小編感覺(jué)到了。。。(自行腦補(bǔ)),在不斷的探索下,終于完成了在上面的基礎(chǔ)適配iPhone X的網(wǎng)絡(luò)類(lèi)型獲取。

首先,通過(guò)添加宏判斷是否是iPhone X,如下:

#define?KIsiPhoneX?([UIScreen?instancesRespondToSelector:@selector(currentMode)]???CGSizeEqualToSize(CGSizeMake(1125,?2436),?[[UIScreen?mainScreen]?currentMode].size)?:?NO)

然后通過(guò)層級(jí)結(jié)構(gòu)判斷類(lèi)型,如下:

+?(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;

}

通過(guò)結(jié)構(gòu)獲取WIFI信號(hào)強(qiáng)度

因?yàn)樯厦娅@取SSID和BSSID的方法在iPhone X依然可用,因此就不多加說(shuō)明了,獲取iPhone X信號(hào)強(qiáng)度的方法也類(lèi)似于上方獲取類(lèi)型。首先判斷是否屬于WIFI網(wǎng)絡(luò),然后根據(jù)iPhone X特有的結(jié)構(gòu)找到特定的地方獲取值就行,如下:

#pragma?mark?獲取Wifi信號(hào)強(qiáng)度

+?(int)getWifiSignalStrength{


????intsignalStrength?=?0;

//????判斷類(lèi)型是否為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;

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容