iOS Reachability test

泄露秘密 提交于 2019-12-01 08:35:50
Kishor Kundan

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

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.

Rok Jarc

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!