一般开发者们获取当前网络状态都使用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即可),打印结果为:
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