问题
Today, I had my Beta-version app out in public. I was at a hotel and had not yet obtained the access code for the WiFi. When testing the reachability, I noticed that it didn't fail as it should have. It was connected to WiFi but nothing was actually reachable because I wasn't logged in. This use-case should be covered by reachabilityWithHostname. Here's my code:
In AppDelegate.h:
@interface AppDelegate : UIResponder <UIApplicationDelegate> {
Reachability* hostReach;
Reachability* internetReach;
Reachability* wifiReach;
}
In AppDelegate.m:
internetReach = [Reachability reachabilityForInternetConnection];
[internetReach startNotifier];
wifiReach = [Reachability reachabilityForLocalWiFi];
[wifiReach startNotifier];
hostReach = [Reachability reachabilityWithHostname: @"http://www.google.com"];
[hostReach connectionRequired];
[hostReach startNotifier];
In module(s) that require connectivity:
- (BOOL) isInternetReachable
{
Reachability *currentReach = [Reachability reachabilityForInternetConnection];
NetworkStatus netStatus = [currentReach currentReachabilityStatus];
return (netStatus == ReachableViaWiFi || netStatus == ReachableViaWWAN);
}
Does anyone know how to cover this circumstance?
回答1:
...
[Reachability reachabilityWithHostname: @"http://www.google.com"]
...
You should be using the hostname (without http://
) per Apple's documentation.
回答2:
You are using Reachability wrong. Apple's documentation is very bad so ignore it.
The trick is to attempt to make a network connection without consulting Reachability first. NSURLConnection will fire up the radios and make the connection as needed. Be sure to handle errors, of course.
Reachability is still useful to signal when the network comes back online after going offline. You can retry to connect at that point if you have information that you weren't able to send/receive beforehand.
Also, you shouldn't call Reachability on the main thread. On poor quality networks, especially with high packet loss or broken DNS, Reachability will hang your app for more than 20 seconds and the system will kill you.
回答3:
I use reachability to proof the network layer. When it should be ok than I try to load a one byte file from my server to be really sure. Performance is ok.
BOOL isOnline = [[[RKClient sharedClient] reachabilityObserver] isReachabilityDetermined] != YES || [[RKClient sharedClient] isNetworkReachable];
if(isOnline){
NSData *data = [NSData dataWithContentsOfURL:[[URLManager sharedInstance]availabilityCheckURL]];
NSString *strTemp = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
isOnline = [strTemp isEqualToString:@"1"];
}
回答4:
The Reachability example uses SystemConfiguration's Reachability API:
A remote host is considered reachable when a data packet, sent by an application into the network stack, can leave the local device. Reachability does not guarantee that the data packet will actually be received by the host.
It probably does two things:
- (Repeatedly?) Resolve the hostname to an IP address.
- Watch the routing table and deliver a callback when the "reachability" of that IP changes.
In the case of a captive portal (a.k.a. Wi-Fi login page), http://www.example.com
has to appear to your web browser as a site that redirects you to the login page; this means www.example.com
has to resolve (whether to its actual IP or not) and there has to be a site at that IP to redirect you to the login page.
Reachability is mainly useful for detecting things like airplane mode or getting disconnected from Wi-Fi.
来源:https://stackoverflow.com/questions/15306658/ios-reachability-fails-to-catch-the-case-where-connected-to-wifi-but-not-logged