IOSでOVER HITアプリのように通信状態が悪いときに、ユーザーにわかるようにする処理を実装したいとします。このような場合、Appleが公開しているReachability(ソースコードあり)を使えば、15分ほどで実装が可能です。
また、Reachabilityはサンプルのxcodeプロジェクトを公開しているため、Reachabilityがどのようにして通信状態を検出するのか、動作確認だけならば5分くらいで可能です!
どんなことができるのか?
Reachabilityをつかってできることは以下の通りです
・指定したURLに対してWifiで接続できているかの検出
・指定したURLに対してWWAN(4G,3G回線など)で接続できているかの検出
・ネットワークに接続できない状態の検出
・通信(ネットワーク)状態が変わるとNotificationが発生し状態を検出できる
実際にReachability試した結果について
リアルタイム(ここでは、1秒以下の時間を指す)に状態変化を検出できるか、いろいろ試してみました。その試したことを書きます。
機内モードにしてみる
リアルタイムに状態が変化して、NotReachable(通信不可)状態になったことを確認しました。
端末の設定でWifiをOFFにしてみる
リアルタイムに状態が変化して、NotReachable(通信不可)状態、もしくは4G回線に移行したことを確認しました。
端末の設定でWifi、4G回線をOFFにしてみる
リアルタイムに状態が変化して、NotReachable(通信不可)状態になったことを確認しました。
Wifi装置の電源をOFFにして、wifiを通信不可状態にする
電源を抜いてから15秒位で4Gに遷移しました。つまり、Reachabilityはユーザーが行う操作についてはリアルタイムで通信状態を検出するが、wifiの切断などいきなり通信が切れてしまう状況についてはリアルタイムでは無いようです。
Reachabilityは、指定したURL(ホスト)に接続できるかどうかまで見るため、リアルタイムに通信の監視していたら、端末および相手のサーバに対して負荷をかけてしまうため、監視回数を抑えていると思われます。
実際にサンプルを動かしてみる
1.以下のサイトにアクセスして
サンプルソースファイルをダウンロードします。
URLは以下の通りです。
Reachabilityの解説・サンプルソースの置き場所
2.サンプルソースファイルを開く
xcodeにてサンプルソースファイルを開きます。
IOS端末で実際に動かしたいときは、以下の図を参考にBundle Identifierを修正します。
修正しないと、承認関係のエラーでビルドエラーになるためです。
あとは、実行ボタンを押せば実際に動かして見ることが可能です。
ポイント解説
このままビルドすれば、サンプルソースファイルを動かすことが可能ですが、
ポイントになる部分を解説します。
(1)Reachabilityの本体
あなたが作成しているアプリにReachabilityを導入する場合、サンプルから以下の2つをコピーして反映させます。
・Reachability.h
・Reachability.m
(2)ヘッダーを追加する
Reachabilityを使いたいところで以下のヘッダーを追加します。
#import “Reachability.h”
(3)サンプルソースを参考に実装
実際の実装方法は、サンプルコードをご確認ください。
ここでは、ポイントになるソースコードの解説をします。
//ネットワークの状態が変わったときにNotification受け取れるようにする
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:kReachabilityChangedNotification object:nil];
//ホストの設定
//このサンプルの例では、appleのサイトに接続しています
NSString *remoteHostName = @"www.apple.com";
self.hostReachability = [Reachability reachabilityWithHostName:remoteHostName];
[self.hostReachability startNotifier];
[self updateInterfaceWithReachability:self.hostReachability];
//通信状態が変わったときに呼び出されるコールバック関数
- (void) reachabilityChanged:(NSNotification *)note
{
Reachability* reachability = [note object];
NetworkStatus netStatus = [reachability currentReachabilityStatus];
switch (netStatus)
{
case NotReachable: {
//通信不可状態のときのコードを書く
break;
}
case ReachableViaWWAN: {
//3G,4G回線で接続できるときのコードを書く
break;
}
case ReachableViaWiFi: {
//Wifi回線で接続できるときのコードを書く
//ちなみに、3G,4G回線、Wifi回線のどちらも使えるときはwifiが
//優先されます
break;
}
}
}
まとめ
IOSで端末の通信状態を検出したいのであれば、Reachabilityというライブラリーがあります。OVER HITアプリのように通信状態をユーザーに通知する手段としては有効と言えます。
ただし、リアルタイム(1秒以下の時間)に通信状態の変化までは検出できないようです。
通信状態が問題なしの判定になったとしても、通信エラー時の処理を実装しなくてもよいというわけではありません。
たとえば、課金処理を実装する場合、Reachabilityの判定が通信OKであっても、課金処理が失敗する可能性があります。エラー処理を実装しないと現金で購入したものが反映されないなど思わぬトラブルに繋がることもあります。
Reachabilityで検出できる通信状態は、あくまでも目安として捕らえた方がよいでしょう。