tcd
tcd

Reputation: 1605

Apple Reachability Notifications for Network OR Wi-Fi

This is the code I use with Reachability in my app:

- (void) handleNetworkChange:(NSNotification *)notice
{

    NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];

    if(remoteHostStatus == NotReachable) {
        UIAlertView *alertnew = [[UIAlertView alloc] initWithTitle:@"No Internet Connection!" message:@"Your device lost internet connection!"
                                                       delegate:self
                                              cancelButtonTitle:@"Close"
                                              otherButtonTitles:@"Dismiss", nil];
        [alertnew show];
    } else if (remoteHostStatus == ReachableViaWWAN) {
        //if connected to the Network
        UIAlertView *alertre = [[UIAlertView alloc] initWithTitle:@"Internet Connection!" message:@"Your device re-connected to the internet!"
                                                         delegate:self
                                                cancelButtonTitle:nil
                                                 otherButtonTitles:@"Ok!", nil];
        [alertre show];
    } else if (remoteHostStatus == ReachableViaWiFi) {
        //if connected to Wi-Fi
        UIAlertView *alertre = [[UIAlertView alloc] initWithTitle:@"Internet Connection!" message:@"Your device re-connected to the internet!"
                                                         delegate:self
                                                cancelButtonTitle:nil
                                                otherButtonTitles:@"Ok!", nil];
        [alertre show];
    }

}

I want to alert the users when they lose internet and when they gain it back. But the problem I'm running into is when a user is on an iPhone (with constant network connection) and they connect to Wi-Fi, they get an alert, when they were already connected. So I would only want to alert them if they DIDN'T have an internet connection and connected to Wi-Fi. This code works great for iPod and iPads without data plans, but the problem is on iPhones. Is there something I can do to edit this and make it only show an alert for one or the other?

I tried this code for the last alert:

else if (remoteHostStatus == ReachableViaWiFi && !(remoteHostStatus == ReachableViaWWAN)) {
        //if connected to Wi-Fi but without Network
        UIAlertView *alertre = [[UIAlertView alloc] initWithTitle:@"Internet Connection!" message:@"Your device re-connected to the internet!"
                                                         delegate:self
                                                cancelButtonTitle:nil
                                                otherButtonTitles:@"Ok!", nil];
        [alertre show];
    }

But this didn't fix the problem...

Upvotes: 1

Views: 1865

Answers (1)

NJones
NJones

Reputation: 27147

The basic error in logic of your code is that you are treating three separate states as two states. NetworkStatus in Apple's Reachability example is defined by an enum seen here:

typedef enum {
    NotReachable = 0,
    ReachableViaWiFi,
    ReachableViaWWAN
} NetworkStatus;

Since you essentially want a BOOL (Reachable or Not). Simply compare the current network status to NotReachable. So that in the case of either ReachableViaWiFi or ReachableViaWWAN the BOOL is YES.

BOOL reachable = (_reachability.currentReachabilityStatus != NotReachable); // underbar added for good ivar style.

Now you just have to handle the case where you had WiFi and moved to cellular or vise-versa. For this case you will have to track the state between calls. Add a BOOL ivar named _reachable. Then compare your new value in your observer method.

-(void)reachabilityDidChange:(NSNotification *)note{
    BOOL reachable = (_reachability.currentReachabilityStatus != NotReachable);
    if (reachable != _reachable){
        // State Changed. Inform the user if necessary.
        if (reachable){
            // Connected.
        } else {
            // Lost connection.
        }
    }
    _reachable = reachable;
}

warning: unsolicited advise below

One last note about the idea of these UIAlertViews in general. Alerts are essentially screaming at the user. An alert on reconnection is essentially yelling "HEY!!! EVERYTHING IS OKAY NOW!". I would like to recommend watching session 221 of WWDC2012 where they speak of common design pitfalls. At about 35 minutes in they begin speaking of alerts. It's clear that they are trying to steer developers away from using alerts as much as possible.

Upvotes: 3

Related Questions