pixyzehn blog

iPhone App, Mac App, Programming, Web service, Tool, Evernote, etc

iOSで圏外やWifiなどのネットワーク状態を判別する

http://www.flickr.com/photos/22498907@N02/3117904741
photo by Will Lion


実際に使ってみたことのメモです。


iOSでネットワークの確認、つまり圏外かそうでないかを判別するには公式のライブラリを使用します。


公式のライブラリはこちらのサンプルからダウンロードします。

Reachability – iOS Developer Library


こちらの記事を参考に行いました。


Reachability:iOSでネット接続を確認する公式ライブラリ « TORQUES LABSReachability:iOSでネット接続を確認する公式ライブラリ « TORQUES LABSはてなブックマーク - Reachability:iOSでネット接続を確認する公式ライブラリ « TORQUES LABS


簡単に説明するとサンプルの

・Reachability.h
・Reachability.m

を使用します。


f:id:inagex:20140708124129p:plain


またプロジェクトにSystemConfiguration.frameworkを追加します。


まずNSNotificationCenterを使ってネットワークが変化したときに通知ができるようObserverを設置します。

// Reachabilityのインスタンスを作成し、フィールド変数に代入。インスタンス作成時に、どのサーバーとの通信状態を監視するかを設定
reachablity = [Reachability reachabilityForInternetConnection];

//NSNotificationCenterに、ネットワーク状態が変化した際に通知を受ける対象を指定します。
static dispatch_once_t onceTokenNetwork;
dispatch_once(&onceTokenNetwork, ^{
        [[NSNotificationCenter defaultCenter]
         addObserver:self
         selector:@selector(notifiedNetworkStatus:)
         name:kReachabilityChangedNotification
         object:nil];
});
// ネットワーク監視を開始
[reachablity startNotifier];


そしてネットワークが変化すると、(例えば圏外から4G)以下のメソッドが呼ばれます。

-(void)notifiedNetworkStatus:(NSNotification *)notification {
    
// reachability変数から、現在のネットワーク状態を取得
NetworkStatus networkStatus = [reachablity currentReachabilityStatus];
    
// 受け取ったネットワーク状態に合わせて、処理
    if (networkStatus == ReachableViaWiFi) {
        /**
         *  Wifi
         */
        type = FZNetworkStatusYes;
        [self startWork];
        return;
    } else if (networkStatus == ReachableViaWWAN) {
        /**
         *  3G or 4G
         */
        type = FZNetworkStatusYes;
        [self startWork];

        return;
    } else {
        /**
         *  圏外
         */
        type = FZNetworkStatusNo;
        [self stopWork];
        return;
    }


上記の例だと、Wifiか3Gor4Gの状態になった場合には、startWorkを呼び、圏外になるとstopWorkを呼び出しています。


また実際に使ってみて、圏外からWifiにネットワークが変化するとき、圏外->3Gor4G->Wifiとなるようで、上記の例だとstartWorkが2回呼ばれてしまい、少し処理が不便でした。


そのためstartWorkにて[reachablity stopNotifier]でネットワークの監視を切るのもひとつの方法だと思います。

- (void)startWork
{
// ネットワークNotifierを切る
[reachablity stopNotifier];

// 処理する...
}


まだ試行段階ですが、圏外でも処理ができないものは、ネットワークが3Gor4GやWifiになったら処理を再開されるということができそうです。