How to get Reachability Notifications in iOS in Background when dropping Wi-Fi network?
Asked Answered
W

2

24

I'm using Reachability successfully to determine the status of the network, and to be notified of changes (e.g. Reachability Guide for iOS 4).

My question isn't how to get Reachability up and running, but rather the following.

My AppDelegate handles the Reachability stuff. The app receives notifications (kReachabilityChangedNotification) while the app is running, and when the app is in the Background (applicationDidEnterBackground:).

The app is designed to reload a playing audio stream when it notices that it's lost a Wi-Fi connection, e.g. To test, I turned Wi-Fi on and off in Settings, and everything worked perfectly. In real-world testing, I often lose Wi-Fi connectivity when I exit the range of the access point. I've found that Reachability isn't helping me too much in this case. I'm not sure if it's because Reachability notifications don't come through when the screen is locked, or if Reachability doesn't handle the slow diminishing of signal from an increasingly distant Wi-Fi access point, but regardless I can't figure out why the real-world testing doesn't match the idealized case.

This is what my code looks like. I first set up to receive notifications, and start listening to Reachability:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // check for internet connection
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(checkNetworkStatus:) 
                                                 name:kReachabilityChangedNotification object:nil];

    // Set up Reachability
    internetReachable = [[Reachability reachabilityForInternetConnection] retain];
    [internetReachable startNotifier];    

    ....

    return YES;
}

and then, this is the function that responds to changes in connectivity:

- (void)checkNetworkStatus:(NSNotification *)notice {
    // called after network status changes

    NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
    switch (internetStatus)
    {
        case NotReachable:
        {
            NSLog(@"The internet is down.");
            break;
        }
        case ReachableViaWiFi:
        {
            NSLog(@"The internet is working via WIFI");
            break;            
        }
        case ReachableViaWWAN:
        {
            NSLog(@"The internet is working via WWAN!");
            break;            
        }
    }    
}

The notifications come through even when the app is in the background, but they don't in the real-world testing described above.

Thanks for any help.

Windsail answered 21/3, 2012 at 18:23 Comment(4)
Have you tried a combination of reachabilityForInternetConnection and reachabilityForLocalWifi?Verified
Did you find a solution for this? I'm experiencing a similar problem, and the solutions here don't seem to help or aren't what I'm looking for.Logotype
I don't know that I ever solved my specific problem, as I haven't needed to work on that project lately. Have you made sure the app is running in the background with a background task, per @Hurden's recommendation?Windsail
Yes, that was indeed the solution, though with a slight change. I'll add another answer in case anyone has the same problem.Logotype
H
5

By default in the background state app stays for a short time only, most apps move to the suspended state shortly afterward. That mean the app is in the background but is not executing code. So your custom implemented notification do not work. Must requery NetworkReachability at Wakeup Time in app delegate methodes:

applicationWillEnterForeground:
applicationDidBecomeActive 
Harned answered 25/10, 2012 at 13:20 Comment(0)
L
1

I was working on a VoIP app, which is launched in the background when the iPhone boots up, at which point there might be no network reachability (e.g. if the phone has both a passcode and/or a SIM card with a PIN code). But since the app is launched directly in the background, the delegate method applicationDidEnterBackground: is not called. Instead what I did was use @Hurden's idea directly in application:didFinishLaunchingWithOptions, checking the applicationState to see if the app was actually starting in the background. This enabled my app to get the kReachabilityChangedNotification notification after the phone was unlocked (enabling the WiFi to connect using the stored password).

Logotype answered 14/10, 2013 at 15:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.