2
votes

I wanted to integrate a network status notification into my project and used Apples's Reachability class for this. Nevertheless I might have found a bug in their code or it maybe also caused by the simulator itself.

Code Here:

- (void)start {

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(updateStatus:) 
                                                 name:kReachabilityChangedNotification 
                                               object:nil];

    Reachability *wifi = [[Reachability reachabilityForLocalWiFi] retain];
    [wifi startNotifier];

}

- (void)updateStatus:(NSNotification *)notice {
    NetworkStatus s = [[notice object] currentReachabilityStatus];
    if(s == NotReachable) {
        NSLog(@"Wifi not reachable");
    } else {
        NSLog(@"Wifi is reachable");
    }
}

Now, what happens when "start" is called:

1) the updateStatus message isn't fired - okay, might be not a bug, maybe it is normal behaviour

2) the updateStatus message is fired, when I switch my Mac's Airport off and then the networkstatus is eq. to "NotReachable", BUT when I turn the Mac's Airport on again the updateStatus message will be fired AND THE NETWORKSTATUS STAYS "NotReachable"

When I add in the start method a timer, doing separate requests on the status

- (void)start {

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(updateStatus:) 
                                                 name:kReachabilityChangedNotification 
                                               object:nil];

    Reachability *wifi = [[Reachability reachabilityForLocalWiFi] retain];
    [wifi startNotifier];

    /* Added */
    [NSTimer scheduledTimerWithTimeInterval:0.5F target:self selector:@selector(updateSeparately:) userInfo:nil repeats:YES];
    /* * */

}

and the "updateSeparately" method itself

/* Added */
- (void)updateSeparately:(NSTimer *)timer {

    NetworkStatus s = [[Reachability reachabilityForLocalWiFi] currentReachabilityStatus];

    if(s == NotReachable) {
        NSLog(@"updateSeparately:Wifi not reachable");
    } else {
        NSLog(@"updateSeparately:Wifi is reachable");
    }
}
/* * */

gives me the following outputs in the console for the next scenarios:

1) AirPort is turned on, I start the App and turn the AirPort off

...
2011-07-21 09:41:41.242 MyProject[7091:207] updateSeparately:Wifi is reachable
2011-07-21 09:41:41.742 MyProject[7091:207] updateSeparately:Wifi is reachable
2011-07-21 09:41:42.242 MyProject[7091:207] updateSeparately:Wifi is reachable
2011-07-21 09:41:42.264 MyProject[7091:207] --- Status Change ---
2011-07-21 09:41:42.265 MyProject[7091:207] Wifi not reachable
2011-07-21 09:41:42.743 MyProject[7091:207] updateSeparately:Wifi not reachable
2011-07-21 09:41:43.243 MyProject[7091:207] updateSeparately:Wifi not reachable
2011-07-21 09:41:43.743 MyProject[7091:207] updateSeparately:Wifi not reachable
...

this seems to be correct

2) after the AirPort has been turned off I turn it on again (App still running)

...
2011-07-21 09:45:42.702 MyProject[7133:207] updateSeparately:Wifi not reachable
2011-07-21 09:45:43.202 MyProject[7133:207] updateSeparately:Wifi not reachable
2011-07-21 09:45:43.701 MyProject[7133:207] updateSeparately:Wifi not reachable
2011-07-21 09:45:43.795 MyProject[7133:207] --- Status Change ---
2011-07-21 09:45:43.795 MyProject[7133:207] Wifi not reachable
2011-07-21 09:45:44.200 MyProject[7133:207] updateSeparately:Wifi not reachable
2011-07-21 09:45:44.700 MyProject[7133:207] updateSeparately:Wifi not reachable
2011-07-21 09:45:45.200 MyProject[7133:207] updateSeparately:Wifi not reachable
2011-07-21 09:45:45.701 MyProject[7133:207] updateSeparately:Wifi is reachable
2011-07-21 09:45:46.201 MyProject[7133:207] updateSeparately:Wifi is reachable
2011-07-21 09:45:46.701 MyProject[7133:207] updateSeparately:Wifi is reachable
...

this shows that the NetworkStatus change has been noticed.... but why does it stay "NotReachable" for ~2 seconds?

Does anyone have an explanation for this?

PS. The same thing happens in the Apple's Reachability Sample Project (available here http://developer.apple.com/library/ios/#samplecode/Reachability/Introduction/Intro.html)

Thanks for reading,

Mizer

2
have you tried running on device?bobbypage

2 Answers

3
votes

probably irrelevant at this point (9 months later) but I was checking out this Reachability stuff and found a probable explanation for the 2 second delay from not reachable to reachable. Might be due to name resolving, as explained in http://developer.apple.com/library/ios/samplecode/Reachability/Listings/ReadMe_txt.html#//apple_ref/doc/uid/DTS40007324-ReadMe_txt-DontLinkElementID_7

IMPORTANT: Reachability must use DNS to resolve the host name before it can determine the Reachability of that host, and this may take time on certain network connections. Because of this, the API will return NotReachable until name resolution has completed. This delay may be visible in the interface on some networks.

I guess changing the check from named host (apple.com by default) to an ip should solve the issue.

2
votes

Use this reachability class here

I use it in all my apps and it works really well.