Reachability network change event not firing
Asked Answered
A

4

5

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.

Algy answered 21/12, 2010 at 17:2 Comment(1)
I think the NSNotification line should be declared AFTER you init reachability instance.Clodhopping
A
18

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. :)

Algy answered 21/12, 2010 at 19:30 Comment(2)
Do I need to release this at some point? Possibly in dealloc of my viewcontroller?Algy
In that case, you have to keep a strong reference of the reachability object somewhere (e.g. as a @property of your ViewController class) in order to retain it.Poison
H
0

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!!

Hyperborean answered 21/12, 2010 at 17:18 Comment(1)
hmm I must be doing something seriously wrong. I tried moving it to the AppDelegate and still nothing....Algy
S
-1

You should include systemconfiguration.framework in to your project.

Sam answered 12/4, 2014 at 18:13 Comment(0)
T
-2

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

Tristichous answered 25/11, 2013 at 12:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.