سؤال

My iphone app is pretty simple with one view that handles everything, in viewDidLoad I check to see if we have an internet connection and if we do we load from the web and if not we load from a local resource. And this works fine.

//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
 }

}

To test my handleNetworkChange event I turned off all cellular data but left the wifi on. Within range of the wifi I started the app and everything works perfect. Then I walk outside of the wifi's range, but my handleNetworkChange never fires (tested using an uiAlertView). Standing outside of the wifi's range my app launches the offline message just fine.

My suspicion is that it is an issue with the ViewController's lifecycle, should this code be placed in the AppDelegate function? Possibly that's a better design to start with.

هل كانت مفيدة؟

المحلول

Turns out it was a memory management issue, as I was not retaining the reachability variable, so as soon as it would go out of scope the dealloc would be called and that called the stopNotifier method. Hence no updates as I would walk out of range.

So instead of:

reachability = [Reachability reachabilityForInternetConnection];

I do

reachability = [[Reachability reachabilityForInternetConnection] retain];

and everything works!

One cool thing I learned through all of this is that you can simulate a lost connection in the simulator by simply turning Airport Off. No more having to wander around outside. :)

نصائح أخرى

Take a look at the reachability example from Apple. I believe they start their notifications in the AppDelegate. In one of my apps, I created a boolean variable which is constantly updated by the AppDelegate connectivity update method so in my other view controllers, I just need to call the delegate and check the value of the IsConnected bool.

Just to through another thought in here... I have noticed issues with the reachability class in which it can freeze your app when your checking for reachability. In my new apps, I skip the reachability class altogether and rather relay on the DidFail delegate methods for NSUrlConnection and UIWebView to determine if I have true connectivity. I no longer have to wait for the reachability class to figure it out and fail for me to then decide what to do, I simply proceed with the web call and use the local as a fall back.

Hope this helps!!

You should include systemconfiguration.framework in to your project.

Your application is not running in background.

Please add this method in your delegate Class

- (void)applicationDidEnterBackground:(UIApplication *)application
{ UIApplication* app = [UIApplication sharedApplication];

    UIBackgroundTaskIdentifier __block bgTask = [app beginBackgroundTaskWithExpirationHandler: ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            [app endBackgroundTask:bgTask];
            bgTask = UIBackgroundTaskInvalid;
        });
    }];

}

Thanks

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top