你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發基礎 >> iOS完美的網絡狀態判斷工具

iOS完美的網絡狀態判斷工具

編輯:IOS開發基礎

大多數App都嚴重依賴於網絡,一款用戶體驗良好的的app是必須要考慮網絡狀態變化的.iOSSinger下一般使用Reachability這個類來檢測網絡的變化.

Reachability

這個是蘋果開發文檔裡面的一個類,官方寫的,用來判斷網絡的變化,包括無網絡,wifi,和蜂窩三種情況.Reachability類實際上是蘋果公司對SCNetworkReachability API的封裝,使用方法比較簡單,這裡不再介紹.說說它的優缺點:


優點

   使用簡單,只有一個類,官方還有Demo,容易上手 

   靈敏度高,基本網絡一有變化,基本馬上就能判斷出來

   能夠判斷有網狀態的切換比如2G/3G/4G切換

缺點

   不能判斷路由器本身是否能聯網

   能否連接到指定服務器,比如國內訪問牆外的服務器

   有網,但是信號很差,網速很慢,跟沒網一樣.這時候應該認為無網.

   

解決方案

事實上Reachability已經很好了,但是實際上客戶端到達服務器需要很多道"關卡",例如路由器,電信服務器,防火牆等.其實說白了就是解決一個問題:客戶端是否能夠成功訪問服務器.這裡介紹另外一個官方的類:SimplePing點我查看


SimplePing

SimplePing也是官方文檔的一個類,目的是ping服務器,可以判斷客戶端是否可以連接到指定服務器.ping 類似於心跳包功能,隔一段時間就ping下服務器,看是否暢通無阻.因此ping不可能做到及時判斷網絡變化,會有一定的延遲.可能大家已經猜到了我的思路,沒錯,把他們兩個合在一起.下面說說我的思路:


  首先利用Reachability判斷設備是否聯網,至於能不能連接到服務器用ping來檢查

  如果Reachability判斷為有網,並且ping也判斷為有網,那麼表示真的有網,否則就是沒網.

  ping 雖然能夠判斷客戶端到服務器是否暢通,但是由於網絡抖動或者網絡很弱等原因,可能出現ping失敗的情況,解決方案就是加上失敗次數限制,超過限制就認為斷網了.

  2/3/4G切換的時候,Reachability雖然檢測到了網絡變化,但是類型還是蜂窩移動,不能給出具體的網絡類型.這裡可以通過獲取狀態欄上的屬性來判斷.

  - (SGNetworkStatus)netWorkDetailStatus{
    UIApplication *app = [UIApplication sharedApplication];
    UIView *statusBar = [app valueForKeyPath:@"statusBar"];
    UIView *foregroundView = [statusBar valueForKeyPath:@"foregroundView"];
    
    UIView *networkView = nil;
    
    for (UIView *childView in foregroundView.subviews) {
        if ([childView isKindOfClass:NSClassFromString(@"UIStatusBarDataNetworkItemView")]) {
            networkView = childView;
        }
    }
    
    SGNetworkStatus status = SGNetworkStatusNone;
    
    if (networkView) {
        int netType = [[networkView valueForKeyPath:@"dataNetworkType"]intValue];
        switch (netType) {
            case 0:
                status = SGNetworkStatusNone;
                break;
            case 1://實際上是2G
                status = SGNetworkStatusUkonow;
                break;
            case 2:
                status = SGNetworkStatus3G;
                break;
            case 3:
                status = SGNetworkStatus4G;
                break;
            case 5:
                status = SGNetworkStatusWifi;
                break;
            default:
                status = SGNetworkStatusUkonow;
                break;
        }
    }
    return status;
}


  可喜的是,即使隱藏了狀態欄,判斷依然有效!


其他細節

默認采用host為`www.baidu.com`,別噴我,不是給百度打廣告,而是因為百度真的只適合判斷有沒有網,因為響應真的很快.當然也可以用自己的服務器地址,這樣更加真實,萬一你家的服務器很渣或者突然crash了也能夠完美判斷.

判斷具體網絡類型的時候,實際上用kvc獲取了控件的私有屬性,根據網上的反應,沒有因此被拒的情況,因此不用擔心.如果因為這個原因被拒,請聯系我第一時間修改.

支持全局通知和代理的方式.默認全局發送通知,如果設置了'delegate'這個屬性,那麼只有代理會收到通知,不在發送全局通知.如果想兩種方式並存,可以新建一個'SGNetObserver'對象.

       

  PS:貌似蘋果官方的原話是'調用了系統的私有api會被拒'.

  

支持模擬器,支持IPv4,IPv6


詳細代碼在這裡:GitHub地址  支持cocoapods,歡迎使用!

  

最後,如果有什麼不對,歡迎大家留言指正.


  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved