为什么Reachability Manager无法检测到互联网?
我正在学习AFNetworking。 当我运行下面的代码,我得到没有互联网。 但在另一个检查说,它连接到互联网和设备通过WiFi连接到互联网。 这个输出:
2016-02-19 15:16:40.315 AFNetworkingSample[377:47927] There is no internet connection 2016-02-19 15:16:40.331 AFNetworkingSample[377:47927] Reachability: Reachable via WiFi
任何想法为什么连接方法的返回值是错误的?
- (void)viewDidLoad { [super viewDidLoad]; [[AFNetworkReachabilityManager sharedManager] startMonitoring]; if (self.connected) { NSLog(@"We have internet connection"); } else { NSLog(@"There is no internet connection"); } [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { NSLog(@"Reachability: %@", AFStringFromNetworkReachabilityStatus(status)); }]; } -(BOOL)connected { return [AFNetworkReachabilityManager sharedManager].reachable; }
更新当我改变它跟随它工作正常,并正确地检测互联网。 任何人都可以解释此行为?
[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { NSLog(@"Reachability: %@", AFStringFromNetworkReachabilityStatus(status)); if (self.connected) { NSLog(@"We have internet connection"); } else { NSLog(@"There is no internet connection"); } }];
UPDATE2
当我等待两秒钟,它检测到互联网正常:
double delayInSeconds = 2.0; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ if (self.connected) { NSLog(@"We have internet connection"); } else { NSLog(@"There is no internet connection"); } });
UPDATE3:
这是如何练习,以避免竞争条件?
- (void)viewDidLoad { [super viewDidLoad]; [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { NSLog(@"Reachability: %@", AFStringFromNetworkReachabilityStatus(status)); if([AFNetworkReachabilityManager sharedManager].reachable) { NSLog(@"Internet connection started again"); } else { UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Alert" message:@"Error Retrieving Data" preferredStyle:UIAlertControllerStyleActionSheet]; UIAlertAction *firstAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { NSLog(@"You pressed button OK"); }]; [alert addAction:firstAction]; [self presentViewController:alert animated:YES completion:nil]; } }]; double delayInSeconds = 2.0; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ [[AFNetworkReachabilityManager sharedManager] startMonitoring]; }); }
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
以上是有效的asynchronous调用。 你已经告诉AFNetwork
你对可达性感兴趣。 因此,它将会停下来,做任何需要做的事来确定和监控后台的可达性。
由于它不是一次性asynchronous调用,因此在该方法上具有完成块并不适合正常完成处理程序的模式。 它可能是一个“状态处理程序”,每当状态发生变化时就被调用,但API也被devise用于被动轮询(其中一些其他的代码模式,如定时器,无意中这样做)正如你所指出的那样,没有足够长的时间给你错误的答案,如预期的那样)。
通过调用setReachabilityStatusChangeBlock:
当可达性状态改变时,你正在注册一些代码来执行。 使用它来触发你的“嘿!可达性改变!” 代码,一切都很好。
剩下的唯一问题是是否存在竞争条件。 您应该在调用startMonitoring
之前设置该块。 而且,为了安全起见,在调用startMonitoring
之后,您可能需要检查networking是否立即连接,因为在技术上,如果networking已连接,则可能没有状态变化触发您的状态改变处理程序块。
你不想阻塞线程2秒,试图避免竞争条件。 做这样的事情:
... set up change handler block ... ... start monitoring ... ... check current internet state & alert user if necessary ...
将您的警报移出更改处理程序块,并将其更改为上面提及的更改处理程序块和“检查当前互联网状态和警报用户”(如果需要)的方法。
使用像这样的可达性…..
- (void)viewDidLoad { if (self.isConnected) { NSLog(@"We have internet connection"); } else { NSLog(@"There is no internet connection"); } } -(BOOL)isConnected { Reachability *aReachability = [Reachability reachabilityWithHostName:KWebserviceURL]; NetworkStatus netStatus = [aReachability currentReachabilityStatus]; if(netStatus==0) { // NoAccess return NO; } else if(netStatus==1) { // ReachableViaWiFi return YES; } else if(netStatus==2) { // ReachableViaWWAN return YES; } else { // Reachable return YES; } }
如果你想使全球classror检查互联网连接,然后让NSObject看到我的另一个答案…. 检查这里
希望它能帮助你…