Need some help with Reachability (2.0.3ddg)
When my app launches, I check for reachability because I need an immediate internet connection. My problem, though, is that it appears there's no immediate confirmation for the NetworkStatus
, which means right after the Reachability is setup, I check whether there's a connection, and it returns that there isn't, regardless of whether I am in fact on WiFi/3G, or have turned the radio off.
I can confirm that I am in fact getting an Internet connection, because instantly after applicationDidFinishLaunching, there's a notification which then logs "ReachableViaWiFi"..
What am I doing wrong? Why is it not confirming a valid Internet connection right away?
- (void)applicationDidFinishLaunching:(UIApplication *)application {
NetworkStatus netStatus = [hostReach currentReachabilityStatus];
if (netStatus == NotReachable) {
ErrorViewController *errorViewController = [[ErrorViewController alloc] initWithNibName:@"ErrorView" bundle:[NSBundle mainBundle]];
[tabBarController.view removeFromSuperview];
[window addSubview:[errorViewController view]];
return;
}
}
-(void)setupReachability {
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(reachabilityChanged:) name:kReachabilityChangedNotification object: nil];
hostReach = [[Reachability reachabilityWithHostName:@"www.google.com"] retain];
[hostReach startNotifier];
}
-(void)reachabilityChanged:(NSNotification *)notification {
Reachability* curReach = [notification object];
NSParameterAssert([curReach isKindOfClass: [Reachability class]]);
NetworkStatus netStatus = [curReach currentReachabilityStatus];
BOOL connectionRequired = [curReach connectionRequired];
switch (netStatus)
{
case NotReachable:
{
[[NSUserDefaults standardUserDefaults] setInteger:kNOTREACHABLE forKey:kREACHABILITYSTATUS];
NSLog(@"NotReachable");
connectionRequired = NO;
break;
}
case ReachableViaWWAN:
{
[[NSUserDefaults standardUserDefaults] setInteger:kREACHABLEVIAWWAN forKey:kREACHABILITYSTATUS];
NSLog(@"R开发者_如何学CeachableViaWWAN");
break;
}
case ReachableViaWiFi:
{
[[NSUserDefaults standardUserDefaults] setInteger:kNOTREACHABLE forKey:kREACHABILITYSTATUS];
NSLog(@"ReachableViaWiFi");
break;
}
}
}
OK, so after trying a few things out myself, I actually got it to work, by adding one extra line of code:
-(void)setupReachability {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reachabilityChanged:) name:kReachabilityChangedNotificationV2 object:nil];
hostReach = [[ReachabilityV2 reachabilityWithHostName:@"www.google.com"] retain];
[hostReach connectionRequired]; // this line was added, and apparently forces a connection requirement..
[hostReach startNotifier];
}
The Reachability sample code provides you with asynchronous callbacks/notifications to inform you of how/when the reachability has changed. In order for your code to work, you should modify your code as follows:
- (void) applicationDidFinishLaunching:(UIApplication *)application {
// setup reachability
[self setupReachability];
}
Then in your callback, when you get the notification you react as needed by your application.
In other words, you can not check immediately for the network status in applicationDidFinishLaunching()
. If you want to do so, then you must use a synchronous/blocking method, for instance you can use the code provided in my answer to this question.
You have to make hostReach as class level variable.
精彩评论