Runtime的使用之获取当前网络状态

一般开发者们获取当前网络状态都使用Reachability,今天我来介绍一个特别的方法,其中使用到的主要技术为runtime和kvc。

KVC不做太多介绍,比较基础,对于runtime,可能初中级开发者比较陌生,其实一开始可以不必去深究,只要记住它的几个关键方法即可,接触多了,自然就懂。

每个ios设备都有状态栏,状态栏上面有个显示网络状态的图标,所以我们可以通过获取这个图标对应的状态来判断网络的状态。

runtime用到的方法:class_copyIvarList(获取类的所有成员变量), ivar_getName(获取变量的名)

NetStatus.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <objc/runtime.h>
@interface NetStatus : NSObject

+(NSInteger)getNetStatus;//(0 - 无网络; 1 - 2G; 2 - 3G; 3 - 4G; 5 - WIFI)

@end

NetStatus.m

#import "NetStatus.h"
@implementation NetStatus
+(NSInteger)getNetStatus{
UIApplication *app = [UIApplication sharedApplication];//获取当前app
//遍历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\n", ivar_getName(ivar));
}
//可以看到有个状态栏,所以:


id statusBar = [app valueForKeyPath:@"statusBar"];

//同上获取statusBar的所有变量(把上面的方法的app替换为statusBar即可),打印结果为:


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

NSArray *array=[[[UIApplicationsharedApplication] valueForKeyPath:@"statusBar.foregroundView"]subviews];
/
/打印出所有子视图,发现其中有个是UIStatusBarDataNetworkItemView,很明显是我们所需要的那个,然后

id networkItemView;//获取到这个视图

for ( id class in array) {if ([class isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {

            networkItemView=class;

        }

//同上获取<networkItemView的所有变量(把上面的方法的app替换为networkItemView即可),打印结果为:


//看来_dataNetworkType就是我们需要的值,但不知道其属于什么类型,用KVC取出来先:
dataNetworkType =[networkItemView valueForKey:@"dataNetworkType"];
//打印它可以确定其为 NSNumber型 NSLog ( @" 当前网络状态是 (0 - no network; 1 - 2G; 2 - 3G; 3 - 4G; 5 - WIFI):%@" ,_dataNetworkType);
 

return [_dataNetworkTypeintegerValue];

//完毕 }

附简化后代码:

+(NSInteger)getNetStatus
{   id networkItemView;
    NSArray *array=[[[UIApplication sharedApplication] valueForKeyPath:@"statusBar.foregroundView"] subviews];
    for (id class in array) {
        if ([class isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {
            networkItemView=class;
        }
    }
    id _dataNetworkType =[networkItemView valueForKey:@"dataNetworkType"];
    NSLog(@"当前网络状态是(0 - no network; 1 - 2G; 2 - 3G; 3 - 4G; 5 - WIFI):%@",_dataNetworkType);
    return [_dataNetworkType integerValue];
}

延伸:通过runtime可以很迅速而且准确的获取到当前网络状态,效果甚至比 Reachability更好,但是这只是主动获取,并不能实时监听app当前网络状态的改变,所以下篇文章我会为大家介绍如何通过runtime来获取状态栏的网络图标更换事件方法以此达到网络状态改变的实时监听(类似Reachability的 kReachabilityChangedNotification )。

本文非100%原创,借鉴了很多优秀的博客进行了整理和汇总,联系QQ:390344868




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值