Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect the reachability in background

I have been testing different way to implement the possibility to know if the device get internet back when the app it is in background so the first code I test was the Apple reachability sample code http://developer.apple.com/library/ios/#samplecode/Reachability/Introduction/Intro.html

But this code doesn´t notify internet state when the App it´s in background. So I tried also the folowing code and it work when App is launched from Background state to foreground (same as Apple reachability sample code)

- (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];

 ...
 }


 - (void)applicationDidEnterBackground:(UIApplication *)application {

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

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

}



- (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");

        //Alert sound in Background when App have internet again
        UILocalNotification *notification = [[[UILocalNotification alloc] init] autorelease];
        if (notification) {
            [notification setFireDate:[NSDate date]];
            [notification setTimeZone:[NSTimeZone defaultTimeZone]];
            [notification setRepeatInterval:0];
            [notification setSoundName:@"alarmsound.caf"];
            [notification setAlertBody:@"Send notification internet back"];
            [[UIApplication sharedApplication] scheduleLocalNotification:notification];
        }


        break;
    }
    case ReachableViaWWAN:
    {
        NSLog(@"The internet is working via WWAN!");


        //Alert sound in Background when App have internet again
        UILocalNotification *notification = [[[UILocalNotification alloc] init] autorelease];
        if (notification) {
            [notification setFireDate:[NSDate date]];
            [notification setTimeZone:[NSTimeZone defaultTimeZone]];
            [notification setRepeatInterval:0];
            [notification setSoundName:@"alarmsound.caf"];
            [notification setAlertBody:@"Send notification internet back"];
            [[UIApplication sharedApplication] scheduleLocalNotification:notification];
        }

        break;
    }
}
}

My question is : What is the way to get notified when internet state changed when the app is in Background ?

like image 456
Ben Avatar asked Oct 01 '12 09:10

Ben


2 Answers

Live you cannot change if the network connection changed, the very best you can do to make it work is to use Background Fetch mode from Capabilities. Firstable you need to check the checkbox for background mode: enter image description here

Then you need to ask for time interval as often as you can the sooner the better so i suggest application:didFinishLaunchingWithOptions: and you need to put this line:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
    return YES;
}

The UIApplicationBackgroundFetchIntervalMinimum it's as often as possible, but it's not exact number of seconds between fetches from the docs:

The smallest fetch interval supported by the system.

And then when background fetch will fire you can check in AppDelegate with method:

-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
    Reachability *reachability = [Reachability reachabilityForInternetConnection];
    [reachability startNotifier];
    NetworkStatus status = [reachability currentReachabilityStatus];

    switch (status) {
        case NotReachable: {
            NSLog(@"no internet connection");
            break;
        }
        case ReachableViaWiFi: {
            NSLog(@"wifi");
            break;
        }
        case ReachableViaWWAN: {
            NSLog(@"cellurar");
            break;
        }
    }
    completionHandler(YES);
}

All of this will work in iOS 7.0 or higher.

like image 126
Jakub Avatar answered Oct 18 '22 11:10

Jakub


I don't believe there is a way to receive reachability notifications while you're in the background. The correct way to handle this would be to check for reachability in AppDelegate's - (void)applicationWillEnterForeground:(UIApplication *)application.

The only background event that background apps react to is receipt of push notifications, and that is because the OS wakes them up to do so, and then only when the user requests it.

like image 42
Gordon Dove Avatar answered Oct 18 '22 12:10

Gordon Dove