一、概述
在开发中, 实时监测网络变化有时候是有必要的, 好处啥的就不用说了.
网上类似的文章还是不少的, 但对方法种类的总结还是不够齐全, 这里本猿就勉为其难的搞搞自认为比较齐全的;
目前来说, 实时检测网络变化的方法主要有四个, 分别是:
- Reachability --- 苹果官方的
- AFNetworkReachabilityManager ---- AFNetWorking自带的
- 第三方框架
- 检测状态栏图标变化
这些个方法里面, 哪个好用点呢???? 老实人不卖关子, 直接说结论吧:
方法 | 特点 | 推荐程度 |
---|---|---|
Reachability | 苹果自带的, 方便简单 | **** |
AFNetworkReachabilityManager | AFNetWorking自带的, 使用也很方便, 而且很多时候使用起来更方便 | ***** |
第三方框架 | 方便但是需要另外导入框架 | **** |
检测状态栏图标变化 | 通过检测状态栏图标来实现检测网络, 存在一定的局限性 | ** |
综合来说, 首先推荐的还是AFNetworkReachabilityManager, 因为我们开发最常用的网络请求框架就是AFNetWorking, 用起来本来就不错, 而且不用再另外导入别的框架了.
下面一个个来试试吧
二、栗子代码
1. Reachability检测网络变化
2. AFNetworkReachabilityManager检测网络变化
这个方法可以分为两种来使用, 一种是直接使用, 另一种是进行自定义的封装成一个netTool工具类来使用, 下面上代码:
3.1直接使用
#pragma mark- AFNetworkReachabilityManager检测网络变化
- (void)AFNetworkReachabilityManagerNetStatus{
__weak typeof(self)weakSelf = self;
[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
NSString *statusStr = [[NSString alloc] init];
switch (status) {
case AFNetworkReachabilityStatusUnknown:
statusStr = @"未知网络";
break;
case AFNetworkReachabilityStatusNotReachable:
statusStr = @"当前网络不可用";
break;
case AFNetworkReachabilityStatusReachableViaWWAN:
statusStr = @"当前网络为WWLAN";
break;
case AFNetworkReachabilityStatusReachableViaWiFi:
statusStr = @"当前网络为WIFI";
break;
default:
break;
}
// [weakSelf alertNetStatusWith:statusStr];
UIAlertView *alV = [[UIAlertView alloc] initWithTitle:statusStr message:@"当前网络状态!!!!" delegate:self cancelButtonTitle:@"知道了" otherButtonTitles:nil, nil];
[alV show];
}];
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
}
3.2 封装成netTool工具类使用
新建一个继承自AFHTTPSessionManager的工具类RSNetTool(名字按照自己的习惯或者命名规则起就好了), 这样做的好处就是在项目的大量网络请求中, 只需要调用shareManager这个方法就能完成网络请求需要的部分参数设置和网络监测; 文件中代码分别是:
.h 文件中
#import "AFHTTPSessionManager.h"
@interface RSNetTool : AFHTTPSessionManager
/**
网络请求单例
@return 返回单例
*/
+ (instancetype)shareManager;
@end
.m文件中:
#import "RSNetTool.h"
@implementation RSNetTool
+ (instancetype)shareManager{
static dispatch_once_t onece;
static id manager;
_dispatch_once(&onece, ^{
manager = [[self alloc] init];
});
return manager;
}
- (instancetype)init{
if (self = [super init]) {
/*
第一部分, 请求的参数和需要的设置
*/
// 设置最大网络访问时间, 默认是60s
self.requestSerializer.timeoutInterval = 20;
// 添加相应格式
[self.requestSerializer setValue:@"application/x-www-form-urlencoded;charset=UTG-8" forHTTPHeaderField:@"Content-Type"];
// 有的网络请求需要设置请求头参数
NSDictionary *headerFieldDic = @{
@"key" : @"value"
};
// 请求头
self.requestSerializer = [AFHTTPRequestSerializer serializer];
// 把参数设置请求头里面
if (headerFieldDic != nil) {
for (NSString *httpHeaderField in headerFieldDic.allKeys) {
NSString *value = headerFieldDic[httpHeaderField];
[self.requestSerializer setValue:value forHTTPHeaderField:httpHeaderField];
}
}
/*
第二部分, 监听网络状态
*/
__weak typeof(self)weakSelf = self;
[self.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
NSString *statusStr = [[NSString alloc] init];
switch (status) {
case AFNetworkReachabilityStatusUnknown:
statusStr = @"未知网络";
break;
case AFNetworkReachabilityStatusNotReachable:
statusStr = @"当前网络不可用";
break;
case AFNetworkReachabilityStatusReachableViaWWAN:
statusStr = @"当前网络为WWLAN";
break;
case AFNetworkReachabilityStatusReachableViaWiFi:
statusStr = @"当前网络为WIFI";
break;
default:
break;
}
// 弹窗提示当前网络
UIAlertView *alV = [[UIAlertView alloc] initWithTitle:statusStr message:@"当前网络状态!!!!" delegate:weakSelf cancelButtonTitle:@"知道了" otherButtonTitles:nil, nil];
[alV show];
}];
// 开始监听
[self.reachabilityManager startMonitoring];
}
return self;
}
@end
3. 通过状态栏监测网络变化
原理就是通过状态栏里面网络的图标变化来检测, 可想而知, 这种方法存在一个巨大的缺陷: 当网络图标被遮挡或者隐藏的时候就检测不到了, 所以并不推荐这种方法;
- (void)setStatusChangeWithBar{
// app单例
UIApplication *app = [UIApplication sharedApplication];
NSArray *subviewArr = [[[app valueForKeyPath:@"statusBar"] valueForKeyPath:@"foregroundView"] subviews];
int type = 0;
for (id sunbview in subviewArr) {
if ([sunbview isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {
type = [[sunbview valueForKeyPath:@"dataNetworkType"] intValue];
}
}
NSString *netStr = [[NSString alloc] init];
switch (type) {
case 1:
netStr = @"2G";
break;
case 2:
netStr = @"3G";
break;
case 3:
netStr = @"4G";
break;
case 5:
netStr = @"WIFI";
break;
default:
netStr = @"未知王略";//代表未知网络
break;
}
UIAlertView *alertV = [[UIAlertView alloc]initWithTitle:netStr message:@"当前网络状态" delegate:self cancelButtonTitle:@"哦, 知道了" otherButtonTitles:nil, nil];
[alertV show];
}
4. 第三方框架检测网络变化
略(简单的一个字, 看似简单却极具张力, 表达了作者对使用别的第三方框架方法的不屑和摒弃, 反映了当下.......编不下去了), 为什么不举例了呢, 因为网上很多很多啊, 随便搜一下都可以有很多, 基本都差不多, 这里就不举例了, 对, 一个栗子都不给;