在項目中實現(xiàn)網(wǎng)絡(luò)的實時監(jiān)測有兩種方式:一種是采用第三方網(wǎng)絡(luò)請求的網(wǎng)絡(luò)檢測方法瘩例,一種是使用OC自帶的網(wǎng)絡(luò)檢測方法。我項目中采用的是第二種甸各。
具體方法如下:
1垛贤、采用AF的網(wǎng)絡(luò)檢測,并實時發(fā)送通知趣倾,以達到網(wǎng)絡(luò)實時監(jiān)測的目的聘惦。
+ (AFNetworkReachabilityManager *)reachability
{
// 1.獲得網(wǎng)絡(luò)監(jiān)控的管理者
AFNetworkReachabilityManager *mgr = [AFNetworkReachabilityManager sharedManager];
// 2.設(shè)置網(wǎng)絡(luò)狀態(tài)改變后的處理
[mgr setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
// 當(dāng)網(wǎng)絡(luò)狀態(tài)改變了, 就會調(diào)用這個block
switch (status) {
case AFNetworkReachabilityStatusUnknown: // 未知網(wǎng)絡(luò)
NSLog(@"未知網(wǎng)絡(luò)");
[[NSNotificationCenter defaultCenter] postNotificationName:@"NoNetWorkNotification" object:nil userInfo:@{@"flag":@1}];
break;
case AFNetworkReachabilityStatusNotReachable: // 沒有網(wǎng)絡(luò)(斷網(wǎng))
NSLog(@"沒有網(wǎng)絡(luò)(斷網(wǎng))");
[[NSNotificationCenter defaultCenter] postNotificationName:@"NoNetWorkNotification" object:nil userInfo:@{@"flag":@0}];
break;
case AFNetworkReachabilityStatusReachableViaWWAN: // 手機自帶網(wǎng)絡(luò)
NSLog(@"手機自帶網(wǎng)絡(luò)");
[[NSNotificationCenter defaultCenter] postNotificationName:@"NoNetWorkNotification" object:nil userInfo:@{@"flag":@1}];
break;
case AFNetworkReachabilityStatusReachableViaWiFi: // WIFI
NSLog(@"WIFI");
[[NSNotificationCenter defaultCenter] postNotificationName:@"NoNetWorkNotification" object:nil userInfo:@{@"flag":@1}];
break;
}
}];
// 3.開始監(jiān)控
[mgr startMonitoring];
return mgr;
}
代碼寫在網(wǎng)絡(luò)請求的最底層,但是只有在調(diào)用單例的時候才會觸發(fā)網(wǎng)絡(luò)的檢測儒恋,并且是以回調(diào)的時候進行網(wǎng)絡(luò)的檢測善绎,所以個人覺得這種方法比較適合用來判斷是否進行網(wǎng)絡(luò)請求,不適合實時的網(wǎng)絡(luò)監(jiān)測用來改變頁面布局碧浊。
2涂邀、OC自帶的網(wǎng)絡(luò)檢測——Reachability瘟仿。(https://developer.apple.com/library/ios/samplecode/Reachability/Reachability.zip)
Reachability的使用箱锐,首先將Reachability.h及Reachability.m導(dǎo)入工程,其次AppDelegate.h中添加頭文件劳较,之后需要導(dǎo)入SystemConfiguration.framework驹止,最后就是代碼了。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSUserDefaults * user = [NSUserDefaults standardUserDefaults];
[user setObject:@1 forKey:NETWORK];
[user synchronize];
//設(shè)置網(wǎng)絡(luò)檢測的站點
NSString * remoteHostName = @"www.baidu.com";
self.reachablity = [Reachability reachabilityWithHostName:remoteHostName];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachablityStatusChange:) name:kReachabilityChangedNotification object:nil];
[self.reachablity startNotifier];
return YES;
}
-(void)reachablityStatusChange:(NSNotification *)notification
{
Reachability * curReach = [notification object];
//? ? NSParameterAssert([curReach isKindOfClass:[Reachability class]]);(此處不注釋掉網(wǎng)絡(luò)有變化的時候代碼直接crash了观蜗,不清楚為什么)
[self updateInterfaceWithReachablity:curReach];
}
-(void)updateInterfaceWithReachablity:(Reachability *)reachablity
{
if(reachablity == _reachablity)
{
NSUserDefaults * user = [NSUserDefaults standardUserDefaults];
NetworkStatus netStatus = [reachablity currentReachabilityStatus];
switch (netStatus) {
case NotReachable:{
[user setObject:@0 forKey:NETWORK];
[[NSNotificationCenter defaultCenter] postNotificationName:NETWORKCHANGE object:nil userInfo:@{NETWORK:@0}];
}
break;
case ReachableViaWWAN:{
[user setObject:@1 forKey:NETWORK];
[[NSNotificationCenter defaultCenter] postNotificationName:NETWORKCHANGE object:nil userInfo:@{NETWORK:@1}];
}
break;
case ReachableViaWiFi:{
[user setObject:@1 forKey:NETWORK];
[[NSNotificationCenter defaultCenter] postNotificationName:NETWORKCHANGE object:nil userInfo:@{NETWORK:@1}];
}
break;
default:
break;
}
[user synchronize];
}
}
-(void)dealloc
{
[_reachablity stopNotifier];
}
這段代碼里面為什么在發(fā)送通知的時候還需要存沙盒一份呢臊恋?原因是在無網(wǎng)絡(luò)的情況下是沒有必要進行網(wǎng)絡(luò)請求的。但是如果在每個接口前都寫一遍網(wǎng)絡(luò)監(jiān)測墓捻,那未免也太傻了抖仅,所以不如存一份,在進行最底層的網(wǎng)絡(luò)請求前先取出來判斷一下是否有網(wǎng)絡(luò)再決定是否要繼續(xù)進行數(shù)據(jù)請求。
網(wǎng)絡(luò)已經(jīng)檢測了撤卢,隨著網(wǎng)絡(luò)的變化也發(fā)送通知了环凿,在需要監(jiān)測網(wǎng)絡(luò)變化的頁面添加監(jiān)聽,然后根據(jù)網(wǎng)絡(luò)的變化調(diào)整頁面布局或者數(shù)據(jù)請求貌似就好了放吩,但是智听,其實還有一個潛在的問題,那就是當(dāng)從無網(wǎng)狀態(tài)恢復(fù)網(wǎng)絡(luò)狀態(tài)的時候渡紫,發(fā)送通知給各個頁面到推,這個時候需要自動刷新數(shù)據(jù),如果不做任何處理的話惕澎,各個頁面會同時請求數(shù)據(jù)莉测,但是其實我們只需要刷新當(dāng)前頁面的數(shù)據(jù),其他頁面唧喉,當(dāng)進入那個頁面的時候再刷新就好了悔雹。這個時候我們需要怎么做呢?
我采取的也是笨辦法——通過標志位欣喧。進入頁面置為YES腌零,離開頁面置為NO,當(dāng)頁面接收到通知的時候唆阿,只有標志位為YES的時候才會進行數(shù)據(jù)的請求益涧,這樣就解決網(wǎng)絡(luò)恢復(fù)各個頁面同時請求數(shù)據(jù)的問題了。個人覺得應(yīng)該還會有更好的辦法驯鳖,但是目前還沒有想到闲询,之后再補充吧。