3

For our app, we use the following code to check for internet connection whenever the app user is trying to post a message. When we test the feature, it works fine when turning on the airplane mode. Then when we turn off the airplane mode, the call to connected still returns NO. What could be the reason for that? Do we need extra "setup" in the order in order to get it right? such as listen to network state change notifications?

+ (BOOL)connected 
{
    Reachability *hostReach = [Reachability reachabilityForInternetConnection]; 
    NetworkStatus netStatus = [hostReach currentReachabilityStatus];    
    return !(netStatus == NotReachable);
}
tom
  • 14,273
  • 19
  • 65
  • 124

3 Answers3

2

Apple Engineers have suggted that completely relying on Rechability.

From a SO post (source of blockquote)

On a WWDC talk this year the Apple engineer on stage recommended users to never base 
the application internet access on the Reachability example app status. Often     
reachability doesn't provide a complete information (it is based on a complex mechanism)    
and the suggestion provided by the engineer was this:

1. try to do your internet connection, whatever it is the Reachability status; 
   then set your UI hint based on success/fail result
2. if it fails due to networking issue, then register to Reachability and retry again 
   when Reachability gives the green light; this is needed when you want to recover 
   automatically from the fail condition
3. in any case give the user the possibility to "force a retry", whatever is the 
   Reachability status. If it succeeds, reset your UI hint immediately.

What I have done ?

Every time I need to make a connection for example

NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString 
               stringWithFormat:@"http://myadress.com"]]];
[self performSelectorOnMainThread:@selector(responseHandler:)
                       withObject:data waitUntilDone:TRUE];


- (void)responseHandler:(NSData *)responseData {
    if(!responseData) {
       ReachabilityController *reachability = [[ReachabilityController alloc] init];
       [reachability checkReachability];
       return;
    }
   // you handle your data
}

What is happening there is, the reachability will only be tested if the connection was failed. I have made a generic ReachabilityController that only deals with the reachability. I did it so, such that i could make calls from all the other controllers every time i make a request.

My ReachabilityController.m looks like

-(void) checkReachability {
     Reachability* internetAvailable = [Reachability reachabilityForInternetConnection];
     NetworkStatus netStatus = [internetAvailable currentReachabilityStatus];
     NSString *messageText;
     if (netStatus == NotReachable)
     {
         messageText = [NSString stringWithFormat:@"Internet access not available"];
     }
     else
     {
          Reachability *netReach = [Reachability reachabilityWithHostName:host];
          NetworkStatus hostStatus = [netReach currentReachabilityStatus];
          if (hostStatus == NotReachable)
          {
              messageText = [NSString stringWithFormat:@"Host Unreachable"];

          }
          else
          {
              messageText = [NSString stringWithFormat:@"Problem with remote service"];
          }

     }
     NSLog(@"%@", messageText);   
}

It won't crash your app, As you are handling the "nil" data parameter yourself and finally you are determining the cause.

hope this helps!

UPDATE:

Apple may reject your app if you show a false message about the Internet Connectivity. They are very serious about their reputation with the iphone. If the internet connectivity is available but if your app reports that internet connectivity is unavailable, It will be considered very serious

Community
  • 1
  • 1
Kishor Kundan
  • 3,135
  • 1
  • 23
  • 30
1

You should just attempt the network connection and not use Reachability for that. NSURLConnection will cause the radios to start up. Be sure to handle errors when/if it fails, though.

EricS
  • 9,650
  • 2
  • 38
  • 34
0

You're using some kind of convenience constructor to check for reachability - this will not work.

One of best examples of how to use reachability is found here on SO:

https://stackoverflow.com/a/3597085/653513

Or so what EricS suggests and don't use reachability at all - it's a viable option.

Community
  • 1
  • 1
Rok Jarc
  • 18,765
  • 9
  • 69
  • 124
  • We found a lot of timeout crashes in our code when we called Reachability on the main thread. This will happen under certain bad network conditions. So now we only call it on background threads and only use it for "network has come up" notifications rather than "is network available" testing. – EricS Jun 15 '12 at 22:43
  • You shouldn't _call_ Reachability. You set it up and listen to its notifications. – Rok Jarc Jun 16 '12 at 05:57