[iOS] ネットワーク接続状態の検出

2016.12.03

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

1 はじめに

ネットワーク接続中の時のみ使用可能な機能では、切断中にUIをDisabledにしておきたいと言うようなニーズがあると思います。

今回は、このような場合に必要となる、ネットワーク接続状態の取得方法です。

ネットワークの接続状態は、SystemConfigration.frameworkを使用して実装しますが、これをラップしたライブラリであるReachabilityが、Appleから提供されており、通常は、これを利用するのが簡単です。

2 導入方法

(1) CocoaPods

Reachabilityは、CocoaPodsでインストール可能です。

pod 'Reachability'

導入後は、下記のヘッダをインポートすることで利用可能になります。

#import "Reachability.h"

SystemConfigration.frameworkは、自動的に追加されます。

003

(2) サンプルコード

Reachabilityは、サンプルコードとして、下記に置かれています。
Guide and Sample Code Reachability

ここから、Reachability.hとReachability.mを取得して、プロジェクトに追加することでも、利用が可能です。

004

3 利用方法

(1) 到達可否

Reachabilityでは、以下の3種類で、到達可否を取得できます。

// ホスト名を指定して、到達の可能性を取得します
+ (instancetype)reachabilityWithHostName:(NSString *)hostName;

// IPアドレスを指定して、到達の可能性を取得します
+ (instancetype)reachabilityWithAddress:(const struct sockaddr *)hostAddress;

// 0.0.0.0への到達の可能性を取得します
+ (instancetype)reachabilityForInternetConnection;

(2) 接続の種類

先のメソッドの戻り値としてReachabilityのインスタンスを受け取り、currentReachabilityStatusプロパティで接続の種類を確認することができます。

下記は、その一例です。

NSString *hostName = @"www.gogle.com";
Reachability *reachablity = [Reachability reachabilityWithHostName:hostName];
NetworkStatus status = [reachablity currentReachabilityStatus];
switch (status) {
    case NotReachable:
        // 接続不能
        break;
    case ReachableViaWWAN:
        // WWANによる接続
        break;
    case ReachableViaWiFi:
        // Wi-Fiによる接続
        break;
    default:
        NSLog(@"%zd",status);
        break;
}

(3) 接続確立

ダイアルアップや、オンデマンドVPNなど、接続の確立が必要であるかどうかの取得

- (BOOL)connectionRequired;

(4) 通知

Reachabilityでは、接続状態の変化で通知を受け取ることが可能です。

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:kReachabilityChangedNotification object:nil];

そして、パラメータで、現在状態を保持したReachabilityを受け取ることができます。

- (void) reachabilityChanged:(NSNotification *)note
{
    Reachability* currentReachability = [note object];
}

また、Notificationの中断及び再開も可能です。

- (BOOL)startNotifier;
- (void)stopNotifier;

4 注意事項など

(1) reachabilityForLocalWiFiは削除されています

Wi-Fiの接続状況を確認するために、reachabilityForLocalWiFiの使用例を紹介したページが幾つか検索されますが、現在、Bonjourの使用を前提に設計されていた、reachabilityForLocalWiFiは、削除されており利用できません。

002

(2) IPv6

2016/05/05以降、IPv6に完全対応しています。

001 reachabilityWithAddress:のパラメータ、struct sockaddr *へは、sockaddr_in6 及び、sockaddr_inの両方が使用可能です。

(3) DNS

reachabilityWithHostName:で、ホスト名を指定して、到達可否を判断する場合、その名前解決が必要ですが、これに時間がかかる場合、名前解決が完了するまで、NotReachableになることに注意が必要です。

(4) 機内モード

機内モードONにすると、一旦、Wi-FiOFFになりますが、機内モードONの状態でWi-FiONにすることは可能です。

また、Reachability機内モードを検出する事はできません。

アプリで機内モードを検出するには、info.plistにUIRequiresPersistentWiFiキーを追加してYESに設定します。

006

こうすることで、機内モードになった時に、下記のダイアログを表示させることができます。

005

5 最後に

今回は、Reachabilityの利用方法について纏めてみました。 アプリの要求に応じて、到達可否のメソッドを使い分けないと、予想外な動作になってしまう事に注意が必要だと感じました。

6 参考資料


Guide and Sample Code Reachability
Network Overview