问题
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);
}
回答1:
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
回答2:
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.
回答3:
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.
来源:https://stackoverflow.com/questions/11055897/ios-reachability-test