iOS(ネットワークの接続状態の検出)
iOSでネットワークの接続状態を検出する方法です。
さて, iphoneでネットワークへ接続が確認された場合のみ使用可能の機能とか, ユーザへの親切心でネットワークに接続していなければUIをDisabledにしておくとか,
そういった動作を入れたい場合はネットワークへの接続状態をあらかじめコードで調べる方法が必要です。
幸いなことにAppleさんが, サンプルを提供してくださっているのでこれを利用しない手はありません。
Apple Developer Reachability
Reachability.m, Reachability.h を利用します。
Reachability
Versionの違いで多少の違いはでてくるかもしれません。このReachabilityで公開されているメソッドは以下のようなメソッドです。
Method | Description |
---|---|
reachabilityWithHostName | ホストへの接続を調べます |
reachabilityWithAddress | IPアドレスベースの接続を調べます |
reachabilityForInternetConnection | 3G, LTEなどのPhoneのネットワークを調べます |
reachabilityForLocalWiFi | Wifi接続を調べます |
サンプル1(Reachability)
一回限りの検出をするには, Reachabilityを単独で使います。
Reachability* curReach = [Reachability reachabilityForInternetConnection]; NetworkStatus netStatus = [curReach currentReachabilityStatus]; if (netStatus == NotReachable) { // Disconnect } else { // Connect }
サンプル2
さらにこれをObserverにしてリアルタイムで監視します。
NetworkObserver.h
extern NSString const * kNETWORKRCONNECT; extern NSString const * kNETWORKDISCONNECT; @interface NetworkObserver : NSObject -(BOOL)startReachability; @end
NetworkObserver.m
NSString const * kNETWORKRCONNECT = @"Connection"; NSString const * kNETWORKDISCONNECT = @"DisConnection"; @interface NetworkObserver() @property(nonatomic, readwrite)NSMutableDictionary *observers; @property(nonatomic, readwrite)Reachability *internetReach; @property(nonatomic, readwrite)Reachability *wifiReach; @property(nonatomic, readwrite)BOOL connect; @end @implementation NetworkObserver -(BOOL)startReachability { // Initial setting [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name: kReachabilityChangedNotification object: nil]; // 3G self.internetReach = [Reachability reachabilityForInternetConnection]; [self.internetReach startNotifier]; BOOL res3G = [self updateInterfaceWithReachability: self.internetReach]; // Wifi self.wifiReach = [Reachability reachabilityForLocalWiFi]; [self.wifiReach startNotifier]; BOOL resWifi = [self updateInterfaceWithReachability: self.wifiReach]; self.connect = res3G || resWifi; return res3G || resWifi; } -(BOOL) updateInterfaceWithReachability:(Reachability*)curReach { NetworkStatus status = [curReach currentReachabilityStatus]; if( status == NotReachable ) { // Disconnected NSLog(@"Disconnected"); return NO; } else { // 3G, Wifi? if(curReach == self.internetReach) { // 3G NSLog(@"3G"); } else if(curReach == self.wifiReach) { // Wifi NSLog(@"Wifi"); } return YES; } } - (void)reachabilityChanged:(NSNotification*)note { Reachability* curReach = [note object]; NSParameterAssert([curReach isKindOfClass: [Reachability class]]); BOOL res = [self updateInterfaceWithReachability: curReach]; // Resume or Stop if ( self.connect != res ) { self.connect = res; if ( res ) { // Post new notification NSNotification *notification = [NSNotification notificationWithName:(NSString*)kNETWORKRCONNECT object:nil]; [[NSNotificationCenter defaultCenter] postNotification:notification]; } else { // Post new notification NSNotification *notification = [NSNotification notificationWithName:(NSString*)kNETWORKDISCONNECT object:nil]; [[NSNotificationCenter defaultCenter] postNotification:notification]; } } } @end
このコードは簡単です。ネットワークの状態を調べて, wifi, 3Gどちらかが機能していれば, NSNotificationで結果を流すといったものです。
つながっていなければそれをNotificationで飛ばします。
さらに, これはObserverとして,変化があればそれを通知してくれます。