之前写过runtime的一些东西,这次通过runtime获取一些苹果官方不想让你拿到的东西,比如,状态栏内部的控件属性。本文将通过runtime带你一步步拿到状态栏中显示网络状态的控件,然后通过监测该控件的属性来获取当前精确网络状态,比如2G/3G/4G/WIFI。

首先,我们需要拿到状态栏,然后通过runtime去探讨状态栏内部的组成结构。

1、导入运行时头文件

#import "objc/message.h

2、编写运行时代码,获取到当前应用程序的所有成员变量

 #import "ViewController.h"#import "objc/message.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidAppear:(BOOL)animated{//状态栏是由当前app控制的,首先获取当前appUIApplication *app = [UIApplication sharedApplication];// 遍历当前app的所有属性,找到关于状态栏的unsigned int outCount = 0;Ivar *ivars = class_copyIvarList(app.class, &outCount);for (int i = 0; i < outCount; i++) {Ivar ivar = ivars[i];printf("|%s", ivar_getName(ivar));}}@end

直接运行,可以看到打印结果为:

3、可以看app里确实有个关于状态栏的成员变量,我们通过KVC取出它,之前很少用KVC,几乎不知道为什么用,现在知道了,其实在runtime里可以很方便的得到成员

  - (void)viewDidAppear:(BOOL)animated{// 状态栏是由当前app控制的,首先获取当前appUIApplication *app = [UIApplication sharedApplication];id statusBar = [app valueForKeyPath:@"statusBar"];// 遍历状态栏的所有成员unsigned int outCount = 0;Ivar *ivars = class_copyIvarList([statusBar class], &outCount);for (int i = 0; i < outCount; i++) {Ivar ivar = ivars[i];printf("|%s", ivar_getName(ivar));}}

运行后可以看到打印结果为:

4、状态栏里有foregroundView这个成员,应该代表着所有当前显示的视图,通过KVC取出它里面的所有子视图

 // 状态栏是由当前app控制的,首先获取当前appUIApplication *app = [UIApplication sharedApplication];NSArray *children = [[[app valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];for (id child in children) {NSLog(@"--%@", [child class]);}

打印结果为:

5、遍历数组,取出用于显示网络状态的视图,并遍历其内部的所有成员变量

 // 状态栏是由当前app控制的,首先获取当前appUIApplication *app = [UIApplication sharedApplication];NSArray *children = [[[app valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];for (id child in children) {if ([child isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {// 遍历当前状态栏的所有属性,找到关于状态栏的unsigned int outCount = 0;Ivar *ivars = class_copyIvarList([child class], &outCount);for (int i = 0; i < outCount; i++) {Ivar ivar = ivars[i];printf("|%s", ivar_getName(ivar));}}}

打印结果为:

6、下面通过KVC,取出dataNetworkType

 if ([child isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {id type = [child valueForKeyPath:"dataNetworkType"];NSLog(@"_dataNetworkType class is %@, value is %@, [type class], type);}

打印结果为:

可见,dataNetworkType类型是NSNumber,值是5。【以上均为模拟器测试】

经过测试,发现,可能的值为 1,2,3,5 分别对应的网络状态是2G、3G、4G及WIFI。 当没有网络时,隐藏UIStatusBarDataNetworkItemView,无法获取dataNetworkType值

总结:

以下是完整的代码,并经过真机测试:

  - (void)viewDidAppear:(BOOL)animated{// 状态栏是由当前app控制的,首先获取当前appUIApplication *app = [UIApplication sharedApplication];NSArray *children = [[[app valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];int type = 0;for (id child in children) {if ([child isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {type = [[child valueForKeyPath:@"dataNetworkType"] intValue];}}NSLog(@" class="----%d", type); }

打印出的type数字对应的网络状态依次是 : 0 - 无网络 ; 1 - 2G ; 2 - 3G ; 3 - 4G ; 5 - WIFI

建议: 将获取的UIStatusBarDataNetworkItemView保存起来,定时去取它的dataNetworkType,这样就可以实时监控网络状态啦(KVO在这里是行不通的哟)

当然,此方法存在一定的局限性,比如当状态栏被隐藏的时候,无法使用此方法。

iOS开发之runtime的运用-获取当前网络状态相关推荐

  1. iOS开发之runtime(16):设置/获取section数据详解

    背景 在前面的文章中,笔者有讲解如何设置以及获取一个section的数据,demo如下: #import <Foundation/Foundation.h> #import <dlf ...

  2. ios c语言编译环境搭建,iOS开发之runtime(一):runtime调试环境搭建

    本系列博客是本人的源码阅读笔记,如果有 iOS 开发者在看runtime的,欢迎大家多多交流.为了方便讨论,本人新建了一个微信群(iOS技术讨论群),想要加入的,请添加本人微信:zhujinhui20 ...

  3. iOS开发之Runtime关联属性

    2019独角兽企业重金招聘Python工程师标准>>> 首先,推荐给大家一个非常好用的一个网站: 非盈利无广告开发者专用网址导航:http://www.dev666.com/ API ...

  4. iOS开发之Runtime常用示例总结

    深度好文,转载自:https://github.com/lizelu/ObjCRuntimeDemo 经常有小伙伴私下在Q上问一些关于Runtime的东西,问我有没有Runtime的相关博客,之前还真 ...

  5. iOS开发之Xcode常用调试技巧总结

    转载自:iOS开发之Xcode常用调试技巧总结 最近在面试,面试过程中问到了一些Xcode常用的调试技巧问题.平常开发过程中用的还挺顺手的,但你要突然让我说,确实一脸懵逼.Debug的技巧很多,比如最 ...

  6. iOS开发之AVKit框架使用

    2019独角兽企业重金招聘Python工程师标准>>> iOS开发之AVKit框架使用 一.引言 在iOS开发框架中,AVKit是一个非常上层,偏应用的框架,它是基于AVFounda ...

  7. IOS开发之MD5加密和钥匙串的使用-oc

    IOS开发之MD5加密和钥匙串的使用-oc 源码在我的主页,md5加密是用户登录安全的一个保障.不可逆的,可以暴力破解的. // // ViewController.m // MD5演练 // // ...

  8. iOS开发之Accounts框架详解

    2019独角兽企业重金招聘Python工程师标准>>> iOS开发之Accounts框架详解 Accounts框架是iOS原生提供的一套账户管理框架,其支持Facebook,新浪微博 ...

  9. iOS开发之Objective-C(面试篇)-李飞-专题视频课程

    iOS开发之Objective-C(面试篇)-132人已学习 课程介绍         这个系列,我会选取实际面试过程中会问到的难点问题.几乎都是在面试大公司或者技术要求比较高的公司会问到的问题.希望 ...

  10. iOS开发之UI开发(UITableView)

    UITableView 继承自UIScrollView,性能极佳 UITableView的两种样式 UITableViewStylePlain列表样式 UITableViewStyleGrouped ...

最新文章

  1. 让计算机“拥抱”常识
  2. golang错误处理
  3. PAT——程序运行时间 (1026)
  4. 服务器重启后启动Docker命令
  5. [转]php获取含中文字符串长度
  6. 使用 .NET 进行游戏开发
  7. [导入]创建DataTable对象
  8. 配色方案为您的下一个设计项目准备,照着配准没错!
  9. java 接口 白名单,SpringBoot HTTP接口跨域调用及白名单实现
  10. 文本编辑框鼠标丢失问题
  11. Spring AOP原理分析(四)--AnnotationAwareAspectJAutoProxyCreator#postProcessBeforeInstantiation源码解析
  12. android 排序view,Android 中ViewPager重排序与更新实例详解
  13. 文件转Base64格式
  14. 怎么用电脑录音,在电脑上录制音频的方法
  15. oracle清空实例数据,Linux下删除oracle实例
  16. 解决Can not add resource (com.android.aaptcompiler.ParsedResource@a980fbb) to table
  17. 【读书笔记】第二章 过程模型
  18. 自学Java day53 使用jvav实现 字典树 数据结构 从jvav到架构师
  19. 【计算机系统】LC-3中断试验
  20. Stable Diffusion 抠图工具使用小记

热门文章

  1. 发一个成熟好用的电池供电切换电路
  2. ListView普通列表控件的使用
  3. android 入门 (分析: 非匿名内部类 监听功能的实现)
  4. APUE学习笔记 - Chapter 2 . Unix Standardization and Implementations
  5. 如何让一个层关闭之后,就算刷新页面了也不显示。除非关闭页面再次打开
  6. Xcode 12 导出ipa包
  7. mybatis 中collection中需要 open close separator
  8. 035 spring amqp
  9. ps 命令的详细功能解析
  10. Android Media Playback 中的MediaPlayer的用法及注意事项(一)