Reachability类只能区分WIFI和WWAN类型,却无法区分2G网和3G网。

网上也有些方法,却都存在Bug。

经过网上查找资料和测试,基本上总结了以下几种方法:

1、使用导航栏的方式:(私有API)

代码:

  1. typedef enum {
  2. NetWorkType_None = 0,
  3. NetWorkType_WIFI,
  4. NetWorkType_2G,
  5. NetWorkType_3G,
  6. } NetWorkType;
  1. UIApplication *application = [UIApplication sharedApplication];
  2. NSArray *subviews = [[[application valueForKey:@"statusBar"] valueForKey:@"foregroundView"]subviews];
  3.  
  4. NSNumber *dataNetWorkItemView = nil;
  5.  
  6. for (id subView in subviews) {
  7.   if ([subView isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) {
  8. dataNetWorkItemView = subView;
  9. break;
  10. }
  11. }
  12.  
  13. NetWorkType networkType = NetWorkType_None;
  14. switch ([[dataNetWorkItemView valueForKey:@"dataNetworkType"] integerValue]) {
  15. case 0:
  16. NSLog(@"No wifi or cellular");
  17. networkType = NetWorkType_None;
  18. break;
  19. case 1:
  20. NSLog(@"2G");
  21. networkType = NetWorkType_2G;
  22. break;
  23. case 2:
  24. NSLog(@"3G");
  25. networkType = NetWorkType_3G;
  26. break;
  27. default:
  28. NSLog(@"Wifi");
  29. networkType = NetWorkType_WIFI;
  30. break;
  31. }

  32. return networkType;

  

使用这种方法要确保导航栏没有被隐藏,如果导航栏被隐藏则取不到值。另外,该方法存在Bug,通过Reachability类,在网络类型发生改变时,再执行该代码,获取的网络类型数据没有更新。如果程序进入后台再转到前台,重新执行该代码时,便可以重新获取最新的网络类型数据。这样用户体验不好,当用户在移动中,网络类型发生改变,无法获取最新的网络类型,则页面数据无法更新。(PS:如果哪位大神知道,有什么方法可以刷新数据值,望不吝赐教,感谢!)

2、通过SCNetworkReachability类

代码:

  1.   struct sockaddr_in zeroAddress;
  2. bzero(&zeroAddress, sizeof(zeroAddress));
  3. zeroAddress.sin_len = sizeof(zeroAddress);
  4. zeroAddress.sin_family = AF_INET;
  5. SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress); //创建测试连接的引用:
  6. SCNetworkReachabilityFlags flags;
  7. SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
  8.  
  9.   if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
  10. {
  11. return NetWorkType_None;
  12. }
  13.  
  14. NetWorkType retVal = NetWorkType_None;
  15.  
  16. if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
  17. {
  18. retVal = NetWorkType_WIFI;
  19. }
  20.  
  21. if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
  22. (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
  23. {
  24. if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
  25. {
  26. retVal = NetWorkType_WIFI;
  27. }
  28. }
  29.  
  30. if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
  31. {
  32. if((flags & kSCNetworkReachabilityFlagsReachable) == kSCNetworkReachabilityFlagsReachable) {
  33. if ((flags & kSCNetworkReachabilityFlagsTransientConnection) == kSCNetworkReachabilityFlagsTransientConnection) {
  34. retVal = NetWorkType_3G;
  35. if((flags & kSCNetworkReachabilityFlagsConnectionRequired) == kSCNetworkReachabilityFlagsConnectionRequired) {
  36. retVal = NetWorkType_2G;
  37. }
  38. }
  39. }
  40. }
  41.  
  42. 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 时要设置真实的私有库路径,因为我们要用它的可执行文件,只有头文件是不行的。

代码:

  1. NSBundle *b = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/SoftwareUpdateServices.framework"];
  2.  
  3. if ([b load]) {
  4.  
  5. // load Class from STRING
  6.  
  7. SUNetworkMonitor *networkMonitor = [SUNetworkMonitor sharedInstance];
  8. int netType = [networkMonitor currentNetworkType];
  9. NetWorkType networkType = NetWorkType_None;
  10. switch ( netType ) {
  11. case 0:
  12. NSLog(@"No wifi or cellular");
  13. networkType = NetWorkType_None;
  14. break;
  15. case 1:
  16. NSLog(@"WIFI");
  17. networkType = NetWorkType_WIFI;
  18. break;
  19. case 2:
  20. NSLog(@"2G");
  21. networkType = NetWorkType_2G;
  22. break;
  23. case 3:
  24. NSLog(@"3G");
  25. networkType = NetWorkType_3G;
  26. break;
  27. default:
  28. break;
  29. }
  30. return networkType;
  31. }
  32.  
  33. return NetWorkType_None;

  

这种方法可以获取网络类型,并且在网络类型改变时,获取最新的网络类型。目前还没有发现Bug,只是准备阶段的工作比较麻烦。

4、最后一种方法,就是利用IOS7系统自带的API获取。只是,IOS7以下的系统版本需要上述的方法获取网络类型。

iOS获取网络类型的四种方法的更多相关文章

  1. IOS中Json解析的四种方法

    作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有的json代码格式比较混乱,可以使用此“http://www.bejson.com/”网站来进行JSON格式化校验 ...

  2. 【转】IOS中Json解析的四种方法

    原文网址:http://blog.csdn.net/enuola/article/details/7903632 作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有 ...

  3. Java获取文件Content-Type的四种方法

    HTTP Content-Type在线工具 有时候我们需要获取本地文件的Content-Type,已知 Jdk 自带了三种方式来获取文件类型. 另外还有第三方包 Magic 也提供了API.Magic ...

  4. Java获取系统时间的四种方法

    1.Date day=new Date(); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); ...

  5. Java 中转换为String类型的四种方法

    1. 使用 String 的构造方法,用于 byte[], char[], StringBuffer, StringBuilder 类型 2. 使用 String 的静态方法 valueOf() 推荐 ...

  6. js判断类型的四种方法

    typeof:使用typeof可以很方便的判断六种类型:undefined.boolean.string.number.object.function 数组和null会被判断为object类型 ins ...

  7. go语言中获取变量类型的三种方法

    package main import ( "fmt" "reflect" ) func main() { var num float64 = 3.14 // ...

  8. iOS:关于获取网络类型和运营商信息

    目录 1. 获取运营商网络类型 2. 获取运营商信息 返回目录 1. 获取运营商网络类型 Apple的Reachability Sample看起来不错,但是只可以判断是否连接到互联网和是否连接Wifi ...

  9. iOS设置圆角的四种方法

    小小圆角问题,正常情况下,我们不需要过多关心,但当屏幕内比较多的时候,还是有必要了解下性能问题的 一.设置CALayer的cornerRadius 这是最常用的,也是最简单的. cornerRadiu ...

随机推荐

  1. CCF CSP 201503-2 数字排序

    CCF计算机职业资格认证考试题解系列文章为meelo原创,请务必以链接形式注明本文地址 CCF CSP 201503-2 数字排序 问题描述 给定n个整数,请统计出每个整数出现的次数,按出现次数从多到 ...

  2. 【AtCoder】AGC005F - Many Easy Problems

    题解 我们把一个点的贡献转化为一条边的贡献,因为边的数量是点的数量-1,最后再加上选点方案数\(\binom{n}{k}\)即可 一条边的贡献是\(\binom{n}{k} - \binom{a}{k ...

  3. C#基础语法补充

    [学习笔记]前接:https://www.cnblogs.com/aland-1415/p/7360509.html 一.异常处理 1.格式 try{ } catch{ } catch{ } ... ...

  4. Ionic Js十二:导航ion-nav-view

     ion-nav-view 当用户在你的app中浏览时,ionic能够检测到浏览历史.通过检测浏览历史,实现向左或向右滑动时可以正确转换视图. 采用AngularUI路由器模块等应用程序接口可以分为 ...

  5. Django 学习总结(更新中)

    1.常用命令 新建一个项目:django-admin.py startproject project-name 新建一个app:python manage.py startapp app-name 同 ...

  6. Javascript中call方法和apply方法用法和区别

    第一次在博客园上面写博客,知识因为看书的时候发现了一些有意思的知识,顺便查了一下资料,就发到博客上来了,希望对大家有点帮助. 连续几天阅读<javascript高级程序设计>这本书了,逐渐 ...

  7. 支撑大规模公有云的Kubernetes改进与优化 (3)

    这一篇我们来讲网易为支撑大规模公有云对于Kubernetes的定制化. 一.总体架构 网易的Kubernetes集群是基于网易云IaaS平台OpenStack上面进行部署的,在外面封装了一个容器平台的 ...

  8. 【BZOJ 1419】1419: Red is good (概率DP)

    1419: Red is good Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 807  Solved: 343 Description 桌面上有R张 ...

  9. [BZOJ3779]重组病毒(LCT+DFS序线段树)

    同[BZOJ4817]树点涂色,只是多了换根操作,分类讨论下即可. #include<cstdio> #include<algorithm> #define lc ch[x][ ...

  10. Codeforces Round #355 (Div. 2) D. Vanya and Treasure 分治暴力

    D. Vanya and Treasure 题目连接: http://www.codeforces.com/contest/677/problem/D Description Vanya is in ...