iOS获取设备的网络状态(已适配iOS13)【转】

前言

小编最近在项目中遇到了一个问题,除刘海屏以外的iOS设备可以正常的搜索到硬件设备,但是刘海屏就不行。因此,小编花了一点时间研究了一下iOS设备获取当前设备的网络状态。

实现

因为iOS的系统是封闭的,所以是没有直接的APi去获取当前的网络状态。但是道高一尺,魔高一尺。开发者总会有办法获取自己想要的东西。

1.网络状态获取

获取当前的网络类型

获取当前的网络类型是通过获取状态栏,然后遍历状态栏的视图完成的。

先导入头文件,如下:

#import"AppDelegate.h"

实现方法如下:

+(NSString*)getNetworkType{UIApplication*app=[UIApplication sharedApplication];id statusBar=nil;//    判断是否是iOS 13NSString*network=@"";if(@available(iOS13.0,*)){UIStatusBarManager*statusBarManager=[UIApplication sharedApplication].keyWindow.windowScene.statusBarManager;#pragmaclang diagnostic push#pragmaclang diagnostic ignored "-Wundeclared-selector"if([statusBarManager respondsToSelector:@selector(createLocalStatusBar)]){UIView*localStatusBar=[statusBarManager performSelector:@selector(createLocalStatusBar)];if([localStatusBar respondsToSelector:@selector(statusBar)]){statusBar=[localStatusBar performSelector:@selector(statusBar)];}}#pragmaclang diagnostic popif(statusBar){//            UIStatusBarDataCellularEntryid currentData=[[statusBar valueForKeyPath:@"_statusBar"]valueForKeyPath:@"currentData"];id _wifiEntry=[currentData valueForKeyPath:@"wifiEntry"];id _cellularEntry=[currentData valueForKeyPath:@"cellularEntry"];if(_wifiEntry&&[[_wifiEntry valueForKeyPath:@"isEnabled"]boolValue]){//                If wifiEntry is enabled, is WiFi.network=@"WIFI";}elseif(_cellularEntry&&[[_cellularEntry valueForKeyPath:@"isEnabled"]boolValue]){NSNumber*type=[_cellularEntry valueForKeyPath:@"type"];if(type){switch(type.integerValue){case0://                            无sim卡network=@"NONE";break;case1:network=@"1G";break;case4:network=@"3G";break;case5:network=@"4G";break;default://                            默认WWAN类型network=@"WWAN";break;}}}}}else{statusBar=[app valueForKeyPath:@"statusBar"];if([[[selfalloc]init]isLiuHaiScreen]){//            刘海屏id statusBarView=[statusBar valueForKeyPath:@"statusBar"];UIView*foregroundView=[statusBarView valueForKeyPath:@"foregroundView"];NSArray*subviews=[[foregroundView subviews][2]subviews];if(subviews.count==0){//                    iOS 12id currentData=[statusBarView valueForKeyPath:@"currentData"];id wifiEntry=[currentData valueForKey:@"wifiEntry"];if([[wifiEntry valueForKey:@"_enabled"]boolValue]){network=@"WIFI";}else{//                    卡1:id cellularEntry=[currentData valueForKey:@"cellularEntry"];//                    卡2:id secondaryCellularEntry=[currentData valueForKey:@"secondaryCellularEntry"];if(([[cellularEntry valueForKey:@"_enabled"]boolValue]|[[secondaryCellularEntry valueForKey:@"_enabled"]boolValue])==NO){//                            无卡情况network=@"NONE";}else{//                            判断卡1还是卡2BOOL isCardOne=[[cellularEntry valueForKey:@"_enabled"]boolValue];intnetworkType=isCardOne?[[cellularEntry valueForKey:@"type"]intValue]:[[secondaryCellularEntry valueForKey:@"type"]intValue];switch(networkType){case0://无服务                                    network=[NSString stringWithFormat:@"%@-%@",isCardOne?@"Card 1":@"Card 2",@"NONE"];break;case3:network=[NSString stringWithFormat:@"%@-%@",isCardOne?@"Card 1":@"Card 2",@"2G/E"];break;case4:network=[NSString stringWithFormat:@"%@-%@",isCardOne?@"Card 1":@"Card 2",@"3G"];break;case5:network=[NSString stringWithFormat:@"%@-%@",isCardOne?@"Card 1":@"Card 2",@"4G"];break;default:break;}}}}else{for(id subviewinsubviews){if([subview isKindOfClass:NSClassFromString(@"_UIStatusBarWifiSignalView")]){network=@"WIFI";}elseif([subview isKindOfClass:NSClassFromString(@"_UIStatusBarStringView")]){network=[subview valueForKeyPath:@"originalText"];}}}}else{//                非刘海屏UIView*foregroundView=[statusBar valueForKeyPath:@"foregroundView"];NSArray*subviews=[foregroundView subviews];for(id subviewinsubviews){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;}

获取当前的Wifi信息

获取当前的Wifi信息需要借助系统的SystemConfiguration这个库。

先导入头文件,如下:

#import

实现方法如下:

#pragmamark 获取Wifi信息+(id)fetchSSIDInfo{NSArray*ifs=(__bridge_transfer id)CNCopySupportedInterfaces();id info=nil;for(NSString*ifnaminifs){info=(__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);if(info&&[info count]){break;}}returninfo;}#pragmamark 获取WIFI名字+(NSString*)getWifiSSID{return(NSString*)[selffetchSSIDInfo][@"SSID"];}#pragmamark 获取WIFI的MAC地址+(NSString*)getWifiBSSID{return(NSString*)[selffetchSSIDInfo][@"BSSID"];}

获取当前的Wifi信号强度

获取信号强度与获取网络状态有点类似,通过遍历状态栏,从而获取WIFI图标的信号强度。在获取前需注意当前状态是否为WIFI。如下:

+(int)getWifiSignalStrength{intsignalStrength=0;//    判断类型是否为WIFIif([[selfgetNetworkType]isEqualToString:@"WIFI"]){//        判断是否为iOS 13if(@available(iOS13.0,*)){UIStatusBarManager*statusBarManager=[UIApplication sharedApplication].keyWindow.windowScene.statusBarManager;id statusBar=nil;#pragmaclang diagnostic push#pragmaclang diagnostic ignored "-Wundeclared-selector"if([statusBarManager respondsToSelector:@selector(createLocalStatusBar)]){UIView*localStatusBar=[statusBarManager performSelector:@selector(createLocalStatusBar)];if([localStatusBar respondsToSelector:@selector(statusBar)]){statusBar=[localStatusBar performSelector:@selector(statusBar)];}}#pragmaclang diagnostic popif(statusBar){id currentData=[[statusBar valueForKeyPath:@"_statusBar"]valueForKeyPath:@"currentData"];id wifiEntry=[currentData valueForKeyPath:@"wifiEntry"];if([wifiEntry isKindOfClass:NSClassFromString(@"_UIStatusBarDataIntegerEntry")]){//                    层级:_UIStatusBarDataNetworkEntry、_UIStatusBarDataIntegerEntry、_UIStatusBarDataEntrysignalStrength=[[wifiEntry valueForKey:@"displayValue"]intValue];}}}else{UIApplication*app=[UIApplication sharedApplication];id statusBar=[app valueForKey:@"statusBar"];if([[[selfalloc]init]isLiuHaiScreen]){//                刘海屏id statusBarView=[statusBar valueForKeyPath:@"statusBar"];UIView*foregroundView=[statusBarView valueForKeyPath:@"foregroundView"];NSArray*subviews=[[foregroundView subviews][2]subviews];if(subviews.count==0){//                    iOS 12id currentData=[statusBarView valueForKeyPath:@"currentData"];id wifiEntry=[currentData valueForKey:@"wifiEntry"];signalStrength=[[wifiEntry valueForKey:@"displayValue"]intValue];//                    dBm//                    int rawValue = [[wifiEntry valueForKey:@"rawValue"] intValue];}else{for(id subviewinsubviews){if([subview isKindOfClass:NSClassFromString(@"_UIStatusBarWifiSignalView")]){signalStrength=[[subview valueForKey:@"_numberOfActiveBars"]intValue];}}}}else{//                非刘海屏UIView*foregroundView=[statusBar valueForKey:@"foregroundView"];NSArray*subviews=[foregroundView subviews];NSString*dataNetworkItemView=nil;for(id subviewinsubviews){if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView")class]]){dataNetworkItemView=subview;break;}}signalStrength=[[dataNetworkItemView valueForKey:@"_wifiStrengthBars"]intValue];returnsignalStrength;}}}returnsignalStrength;}

2.Reachability的使用

下载开源类Reachability,然后根据文档使用即可(该类把移动网络统称为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;}

上次发布了这篇文章之后,有人问我,怎么才能获取设备的IP地址呢?在这里,小编附上获取iP地址的方法。

先导入头文件,如下:

#import#import

实现方法,如下:

#pragma mark 获取设备IP地址+(NSString*)getIPAddress{NSString*address=@"error";structifaddrs*interfaces=NULL;structifaddrs*temp_addr=NULL;int success=0;// 检索当前接口,在成功时,返回0success=getifaddrs(&interfaces);if(success==0){// 循环链表的接口temp_addr=interfaces;while(temp_addr!=NULL){//                开热点时本机的IP地址if([[NSString stringWithUTF8String:temp_addr->ifa_name]isEqualToString:@"bridge100"]){address=[NSString stringWithUTF8String:inet_ntoa(((structsockaddr_in*)temp_addr->ifa_addr)->sin_addr)];}if(temp_addr->ifa_addr->sa_family==AF_INET){// 检查接口是否en0 wifi连接在iPhone上if([[NSString stringWithUTF8String:temp_addr->ifa_name]isEqualToString:@"en0"]){// 得到NSString从C字符串address=[NSString stringWithUTF8String:inet_ntoa(((structsockaddr_in*)temp_addr->ifa_addr)->sin_addr)];}}temp_addr=temp_addr->ifa_next;}}// 释放内存freeifaddrs(interfaces);returnaddress;}

3.iOS 12下的补充

在iOS 12下xcode需要打开权限才可以正常操作,如下:

image

4.iOS 13下的补充

在iOS 13下xcode需要打开权限才可以正常操作,如下:

image

image

并且,在iOS 13下,若要获取SSID和BSSID,需要添加定位权限

image

#import@interfaceViewController()@property(strong,nonatomic)CLLocationManager*locationManager;@end@implementationViewController-(void)viewDidLoad{[superviewDidLoad];// Do any additional setup after loading the view, typically from a nib.if(@available(iOS13.0,*)){//        如果是iOS13 未开启地理位置权限 需要提示一下if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusNotDetermined){self.locationManager=[[CLLocationManager alloc]init];[self.locationManager requestWhenInUseAuthorization];}}}

到这里为止,这篇文章就结束了。在这里提醒一下各位看官,横屏时请注意不要把状态栏去掉。有说明不足的地方欢迎评论,这里附上Demo下载地址:Demo。最后,希望这篇文章对各位看官们有所帮助。对支持小编的看官们表示感谢。


参考链接:https://wenku.baidu.com/view/0cc38fdeadaad1f34693daef5ef7ba0d4a736d10.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,377评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,390评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,967评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,344评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,441评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,492评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,497评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,274评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,732评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,008评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,184评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,837评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,520评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,156评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,407评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,056评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,074评论 2 352

推荐阅读更多精彩内容