Reachability Network変更イベントは発生しません
-
12-10-2019 - |
質問
私のiPhoneアプリは、すべてを処理する1つのビューで非常にシンプルです。ViewDidloadでは、インターネット接続があるかどうかを確認し、Webからロードしても、ローカルリソースからロードされない場合は確認します。そして、これは正常に機能します。
//in viewDidOnload
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleNetworkChange:)
name:kReachabilityChangedNotification object:nil];
reachability = [Reachability reachabilityForInternetConnection];
[reachability startNotifier];
NetworkStatus status = [reachability currentReachabilityStatus];
if (status == NotReachable) {
//Do something offline
} else {
//Do sometihng on line
}
- (void)handleNetworkChange:(NSNotification *)notice{
NetworkStatus status = [reachability currentReachabilityStatus];
if (status == NotReachable) {
//Change to offline Message
} else {
//Relaunch online application
}
}
HandLenetWorkChangeイベントをテストするために、すべてのセルラーデータをオフにしましたが、WiFiをオンにしました。 wifiの範囲内でアプリを開始しましたが、すべてが完璧に機能します。その後、WiFiの範囲の外を歩きますが、HandLenetWorkChangeは発砲しません(UIALERTVIEWを使用してテストされます)。 WiFiの範囲の外に立っている私のアプリは、オフラインメッセージを正常に起動します。
私の疑いは、それがViewControllerのライフサイクルの問題であるということですが、このコードをAppDelegate機能に配置する必要がありますか?おそらくそれは最初からより良いデザインです。
解決
到達可能性変数を保持していなかったため、メモリ管理の問題であることがわかりました。そのため、範囲外に出るとすぐに、deallocが呼び出され、stopnotifierメソッドと呼ばれます。したがって、私は範囲外に出るので、更新はありません。
だから:の代わりに:
reachability = [Reachability reachabilityForInternetConnection];
そうです
reachability = [[Reachability reachabilityForInternetConnection] retain];
そして、すべてが機能します!
私がこのすべてで学んだクールなことの1つは、空港をオフにするだけで、シミュレーターの失われた接続をシミュレートできることです。もう外をさまよう必要はありません。 :)
他のヒント
Appleの到達可能性の例をご覧ください。彼らはAppDelegateで通知を開始すると思います。私のアプリの1つで、AppDelegate Connectivity Updateメソッドによって常に更新されているブール変数を作成したため、他のビューコントローラーでは、Delegateに電話してISConnected Boolの値を確認する必要があります。
ここの別の考えを通して...私は、到達可能性をチェックするときにアプリをフリーズすることができる到達可能性クラスの問題に気づきました。私の新しいアプリでは、Reachabilityクラスを完全にスキップし、nsurlconnectionとUiwebviewのDidfail Delegateメソッドをむしろリレーして、真の接続性があるかどうかを判断します。 Reachabilityクラスがそれを理解し、何をすべきかを決めるために失敗するのを待つ必要はもうありません。私は単にWebコールを進めて、ローカルをフォールバックとして使用します。
お役に立てれば!!
SystemConfiguration.frameworkをプロジェクトに含める必要があります。
アプリケーションがバックグラウンドで実行されていません。
この方法をデリゲートクラスに追加してください
- (void)applicationDidEnterBackground:(UIApplication *)application
{ UIApplication* app = [UIApplication sharedApplication];
UIBackgroundTaskIdentifier __block bgTask = [app beginBackgroundTaskWithExpirationHandler: ^{
dispatch_async(dispatch_get_main_queue(), ^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}];
}
ありがとう