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

來源:互聯網
上載者:User

標籤:

大多數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,歡迎使用!

  

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

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.