一、概述
在開發(fā)中, 實時監(jiān)測網絡變化有時候是有必要的, 好處啥的就不用說了.
網上類似的文章還是不少的, 但對方法種類的總結還是不夠齊全, 這里本猿就勉為其難的搞搞自認為比較齊全的;
目前來說, 實時檢測網絡變化的方法主要有四個, 分別是:
- Reachability --- 蘋果官方的
- AFNetworkReachabilityManager ---- AFNetWorking自帶的
- 第三方框架
- 檢測狀態(tài)欄圖標變化
這些個方法里面, 哪個好用點呢???? 老實人不賣關子, 直接說結論吧:
| 方法 | 特點 | 推薦程度 |
|---|---|---|
| Reachability | 蘋果自帶的, 方便簡單 | **** |
| AFNetworkReachabilityManager | AFNetWorking自帶的, 使用也很方便, 而且很多時候使用起來更方便 | ***** |
| 第三方框架 | 方便但是需要另外導入框架 | **** |
| 檢測狀態(tài)欄圖標變化 | 通過檢測狀態(tài)欄圖標來實現檢測網絡, 存在一定的局限性 | ** |
綜合來說, 首先推薦的還是AFNetworkReachabilityManager, 因為我們開發(fā)最常用的網絡請求框架就是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:@"當前網絡狀態(tài)!!!!" delegate:self cancelButtonTitle:@"知道了" otherButtonTitles:nil, nil];
[alV show];
}];
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
}
3.2 封裝成netTool工具類使用
新建一個繼承自AFHTTPSessionManager的工具類RSNetTool(名字按照自己的習慣或者命名規(guī)則起就好了), 這樣做的好處就是在項目的大量網絡請求中, 只需要調用shareManager這個方法就能完成網絡請求需要的部分參數設置和網絡監(jiān)測; 文件中代碼分別是:
.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];
}
}
/*
第二部分, 監(jiān)聽網絡狀態(tài)
*/
__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:@"當前網絡狀態(tài)!!!!" delegate:weakSelf cancelButtonTitle:@"知道了" otherButtonTitles:nil, nil];
[alV show];
}];
// 開始監(jiān)聽
[self.reachabilityManager startMonitoring];
}
return self;
}
@end
3. 通過狀態(tài)欄監(jiān)測網絡變化
原理就是通過狀態(tài)欄里面網絡的圖標變化來檢測, 可想而知, 這種方法存在一個巨大的缺陷: 當網絡圖標被遮擋或者隱藏的時候就檢測不到了, 所以并不推薦這種方法;
- (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:@"當前網絡狀態(tài)" delegate:self cancelButtonTitle:@"哦, 知道了" otherButtonTitles:nil, nil];
[alertV show];
}
4. 第三方框架檢測網絡變化
略(簡單的一個字, 看似簡單卻極具張力, 表達了作者對使用別的第三方框架方法的不屑和摒棄, 反映了當下.......編不下去了), 為什么不舉例了呢, 因為網上很多很多啊, 隨便搜一下都可以有很多, 基本都差不多, 這里就不舉例了, 對, 一個栗子都不給;