views:

1238

answers:

4

Hi

I've searched but can't see a similar question.

I've added a method to check for an internet connection per the Reachability example. It works most of the time, but when installed on the iPhone, it quite often fails even when I do have internet connectivity (only when on 3G/EDGE - WiFi is OK).

Basically the code below returns NO.

If I switch to another app, say Mail or Safari, and connect, then switch back to the app, then the code says the internet is reachable. Kinda seems like it needs a 'nudge'.

Anyone seen this before? Any ideas?

Many thanks James

+ (BOOL) doWeHaveInternetConnection{

BOOL success;
// google should always be up right?!
const char *host_name = [@"google.com" cStringUsingEncoding:NSASCIIStringEncoding];

SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL,
                   host_name);
SCNetworkReachabilityFlags flags;
success = SCNetworkReachabilityGetFlags(reachability, &flags);
BOOL isAvailable = success && (flags & kSCNetworkFlagsReachable) && !(flags & kSCNetworkFlagsConnectionRequired);

if (isAvailable) {
 NSLog(@"Google is reachable: %d", flags);
}else{
 NSLog(@"Google is unreachable");
}

return isAvailable;

}

+2  A: 

Looks like you've stripped out some basic reachability code from the Apple example code. What happens when you leave it intact and do this?

Reachability *hostReach = [[Reachability reachabilityWithHostName: @"www.apple.com"] retain];

NetworkStatus netStatus = [hostReach currentReachabilityStatus];

if (netStatus == NotReachable)
{
    NSLog(@"NotReachable");
}

if (netStatus == ReachableViaWiFi)
{
    NSLog(@"ReachableViaWiFi");
}

if (netStatus == ReachableViaWWAN)
{
    NSLog(@"ReachableViaWWAN");
}
Matt Long
Apologies, I am a bit of a noob.I added the example Reachability classes to my project, but can't compile. Reachability *hostReach = [[Reachability reachabilityWithHostName: @"www.apple.com"] retain];Doesn't work. Can't find the reachabilityWithHostName method.I'll keep tweaking ...
stoutyhk
this works:+ (BOOL) doWeHaveInternetConnection2{ if([[Reachability sharedReachability] internetConnectionStatus] == NotReachable) { return NO; } else { return YES; } }
stoutyhk
+1  A: 
+ (BOOL) doWeHaveInternetConnection2{

if([[Reachability sharedReachability] internetConnectionStatus] == NotReachable) {
 return NO;
}
else
{
 return YES; 
}

}

(sorry, code format didn't work in comment)

stoutyhk
The call to `+sharedReachability` tells me you're using a pre-2.0 version of Reachability. The latest version was posted a week or so ago, and it works a lot better than the one that used a singleton. Matt's answer below is based on the latest version, which is why you were having trouble compiling it. Grab the latest version and see if it suits your needs better.
Tim
Thanks - didn't know there was a new version. Many thanks.
stoutyhk
A: 

With version 2, code should be:

+ (BOOL) doWeHaveInternetConnection2{

if([Reachability reachabilityForInternetConnection] == NotReachable) {
 return NO;
}
else
{
 return YES; 
}

}

stoutyhk
//reachabilityForInternetConnection- checks whether the default route is available. // Should be used by applications that do not connect to a particular host
stoutyhk
Testing this last night, on the iphone device, in aeroplane mode, this code returned a YES, but then when retrieving a URL, it failed. So I wouldn't use this. Going back to checking connection to a particular host.
stoutyhk
A: 

What I have found is that you have to be aware of what thread (runloop) from which you first call startNotifier. If you call it from a background thread or NSOperation, you will start the notifier loop on that thread's run loop.

If you share instances, perhaps grabbing a singleton like in [Reachability reachabilityForInternetConnection], it appears from the current code (2.0) that the last invoker wins and gets the notifier set to its run loop.

sehugg