8

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;

}

stoutyhk
  • 243
  • 4
  • 10

4 Answers4

7

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
  • 24,438
  • 4
  • 73
  • 99
  • 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 Aug 15 '09 at 07:09
  • this works: + (BOOL) doWeHaveInternetConnection2{ if([[Reachability sharedReachability] internetConnectionStatus] == NotReachable) { return NO; } else { return YES; } } – stoutyhk Aug 15 '09 at 07:16
  • 1
    that code always give you "NotConnected" though its connected. but once it goes to "reachabilityChanged" method it give you correct status. so how to get correct status in first place? – Nnp Nov 12 '10 at 18:59
1
+ (BOOL) doWeHaveInternetConnection2{
         if([[Reachability sharedReachability] internetConnectionStatus] == NotReachable) {
                   return NO;
          }
          else
          {
                  return YES; 
          }

}

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

Parth Bhatt
  • 19,381
  • 28
  • 133
  • 216
stoutyhk
  • 243
  • 4
  • 10
  • 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 Aug 16 '09 at 21:53
1

With version 2, code should be:

+ (BOOL) doWeHaveInternetConnection2{

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

}

stoutyhk
  • 243
  • 4
  • 10
  • //reachabilityForInternetConnection- checks whether the default route is available. // Should be used by applications that do not connect to a particular host – stoutyhk Aug 19 '09 at 14:16
  • 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 Sep 02 '09 at 01:39
  • Testing a connection to a particular host using reachabilityWithHostName will return a false positive, apparently any time your phone has been assigned an IP address. Try it: Unplug the cable from your wireless router while your phone is connected to it, and check the result of [Reachability reachabilityWithHostName:] It'll be YES every time, even though you obviously can't reach the host. – Oscar Jun 01 '11 at 22:59
1

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
  • 3,615
  • 5
  • 43
  • 60