iOS获取网络类型的方法汇总
Reachability类只能区分WIFI和WWAN类型,却无法区分2G网和3G网。
网上也有些方法,却都存在Bug。
经过网上查找资料和测试,基本上总结了以下几种方法:
1、使用导航栏的方式:(私有API)
代码:
复制代码 代码如下:typedef enum {
NetWorkType_None = 0,
NetWorkType_WIFI,
NetWorkType_2G,
NetWorkType_3G,
} NetWorkType;
UIApplication *application = [UIApplication sharedApplication]; NSArray *subviews = [[[application valueForKey:@"statusBar"] valueForKey:@"foregroundView"]subviews]; NSNumber *dataNetWorkItemView = nil; for (id subView in subviews) { if ([subView isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) { dataNetWorkItemView = subView; break; } } NetWorkType networkType = NetWorkType_None; switch ([[dataNetWorkItemView valueForKey:@"dataNetworkType"] integerValue]) { case 0: NSLog(@"No wifi or cellular"); networkType = NetWorkType_None; break; case 1: NSLog(@"2G"); networkType = NetWorkType_2G; break; case 2: NSLog(@"3G"); networkType = NetWorkType_3G; break; default: NSLog(@"Wifi"); networkType = NetWorkType_WIFI; break; } return networkType;
使用这种方法要确保导航栏没有被隐藏,如果导航栏被隐藏则取不到值。另外,该方法存在Bug,通过Reachability类,在网络类型发生改变时,再执行该代码,获取的网络类型数据没有更新。如果程序进入后台再转到前台,重新执行该代码时,便可以重新获取最新的网络类型数据。这样用户体验不好,当用户在移动中,网络类型发生改变,无法获取最新的网络类型,则页面数据无法更新。(PS:如果哪位大神知道,有什么方法可以刷新数据值,望不吝赐教,感谢!)
2、通过SCNetworkReachability类
代码:
struct sockaddr_in zeroAddress; bzero(&zeroAddress, sizeof(zeroAddress)); zeroAddress.sin_len = sizeof(zeroAddress); zeroAddress.sin_family = AF_INET; SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress); //创建测试连接的引用: SCNetworkReachabilityFlags flags; SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags); if ((flags & kSCNetworkReachabilityFlagsReachable) == 0) { return NetWorkType_None; } NetWorkType retVal = NetWorkType_None; if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0) { retVal = NetWorkType_WIFI; } if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) || (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0)) { if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0) { retVal = NetWorkType_WIFI; } } if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN) { if((flags & kSCNetworkReachabilityFlagsReachable) == kSCNetworkReachabilityFlagsReachable) { if ((flags & kSCNetworkReachabilityFlagsTransientConnection) == kSCNetworkReachabilityFlagsTransientConnection) { retVal = NetWorkType_3G; if((flags & kSCNetworkReachabilityFlagsConnectionRequired) == kSCNetworkReachabilityFlagsConnectionRequired) { retVal = NetWorkType_2G; } } } } return retVal;
这种方法跟Reachability的方法相同,也无法区分2G网和3g网,但是网上有人测试可以区分,如果有人知道原因,希望指正,谢谢!
3、使用SoftwareUpdateService.framework(私有API)
准备工作:
导出生成私有API的头文件声明
使用私有或未公开的API,首先需要导出其对应的头文件,在头文件里有相关函数的声明。
工具:
class-dump
class-dump可以从编译后的Objective-C的二进制文件中提取对应的数据结构及函数等声明。
使用方法:
为了能在任意目录下使用class-dump命令,首先建议把class-dump文件拷贝到/user/local/bin/目录下,然后就可以在任意目录下执行以下命令:
class-dump /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/SoftwareUpdateServices.framework/ >SUKit.h
但是bulidsetting 设置framework的search path 时要设置真实的私有库路径,因为我们要用它的可执行文件,只有头文件是不行的。
代码:
NSBundle *b = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/SoftwareUpdateServices.framework"]; if ([b load]) { // load Class from STRING SUNetworkMonitor *networkMonitor = [SUNetworkMonitor sharedInstance]; int netType = [networkMonitor currentNetworkType]; NetWorkType networkType = NetWorkType_None; switch ( netType ) { case 0: NSLog(@"No wifi or cellular"); networkType = NetWorkType_None; break; case 1: NSLog(@"WIFI"); networkType = NetWorkType_WIFI; break; case 2: NSLog(@"2G"); networkType = NetWorkType_2G; break; case 3: NSLog(@"3G"); networkType = NetWorkType_3G; break; default: break; }<br> return networkType; } return NetWorkType_None;
这种方法可以获取网络类型,并且在网络类型改变时,获取最新的网络类型。目前还没有发现Bug,只是准备阶段的工作比较麻烦。
4、最后一种方法,就是利用IOS7系统自带的API获取。只是,IOS7以下的系统版本需要上述的方法获取网络类型。
以上所述就是本文的全部内容了,希望大家能够喜欢。
您可能感兴趣的文章:
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- js判断客户端是iOS还是Android等移动终端的方法
- IOS开发环境windows化攻略
- .net平台推送ios消息的实现方法
- 探讨Android与iOS,我们将何去何从?
- Android、iOS和Windows Phone中的推送技术详解
- IOS 改变键盘颜色代码
- Android和IOS的浏览器中检测是否安装某个客户端的方法
- javascript实现阻止iOS APP中的链接打开Safari浏览器
- iOS开发之路--微博OAuth授权_取得用户授权的accessToken
- ios通过按钮点击异步加载图片
- ios中图像进行压缩方法汇总
- IOS检测指定路径的文件是否存在
- iOS、Mac OS X系统中编程实现汉字转拼音的方法(超级简单)