为什么可达性管理器无法检测到Internet? [英] Why Reachability Manager can not detect internet?

查看:116
本文介绍了为什么可达性管理器无法检测到Internet?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试学习AFNetworking。当我运行以下代码时,我无法上网。但是在另一项检查中,它说它已连接到互联网,并且设备通过wifi已连接到互联网。输出如下:

I am trying to learn AFNetworking. when I run following code I get there is no internet. But in another check it says it is connected to the internet and device is connected to internet through wifi. This the output:

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

知道连接方法的返回值为何为假吗?

Any idea why return value of connected method is false?

- (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;

}

更新
当我将其更改为跟随时,它可以正常工作并正确检测互联网。任何人都可以解释这种行为吗?

UPDATE When I change it to following it works fine and detect internet properly. Anyone can explain this behaviour?

[[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

当我等待两秒钟时,它可以正确检测到互联网:

When I wait for two second it detects internet properly:

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];

上面实际上是一个异步调用。您已经告诉 AFNetwork 您对可达性感兴趣。这样一来,它就将开始工作,并做任何需要做的事来确定和监视后台的可达性。

The above is, effectively, an asynchronous call. You've told AFNetwork that you're interested in reachability. As such, it is going to go off and do whatever it needs to do to determine and monitor reachability in the background.

由于它不是一次射击异步调用,该方法上有一个 completion块,这实际上不适合常规完成处理程序的模式。可能是状态变化发生时都会被调用的状态处理程序,但该API还被设计为用于被动轮询(您的某些其他代码模式(例如计时器)会无意中这样做-并且,如您所指出的,等待时间不够长会给您错误的答案,如预期的那样。)

Since it is not a one shot asynchronous call, having a completion block on that method doesn't really fit the pattern of a normal completion handler. It could have been a "status handler" that is called whenever a state change happens, but the API is also designed to be used for passive polling (which some of your other code patterns, like the timer one, inadvertently do -- and, as you noted, not waiting long enough gives you the wrong answer, as expected).

通过调用 setReachabilityStatusChangeBlock: ,您正在注册一些在可达性状态更改时要执行的代码。使用它来触发嘿!可达性已更改!代码,一切都很好。

By calling setReachabilityStatusChangeBlock:, you are registering a bit of code to be executed when the reachability status changes. Use that to trigger your "hey! reachability changed!" code, and all is well.

唯一剩下的问题是是否存在比赛条件。您可能应该在调用 startMonitoring 之前设置该块。而且,为了安全起见,您可能希望在调用 startMonitoring 之后立即检查网络是否已连接,因为从技术上讲,如果网络已连接,则

The only remaining issue is whether there is a race condition. You should probably set the block before calling startMonitoring. And, to be safe, you'll likely want to check to see if the network is connected immediately after you call startMonitoring as, technically, if the network was connected, then there may not be a state change that triggers a call to your state changed handler block.

您可能不想触发状态调用阻塞线程2秒钟,以尝试避免出现竞争状况。做这样的事情:

You don't want to block the thread for 2 seconds to try and avoid the race condition. Do something like this:

... set up change handler block ...
... start monitoring ...
... check current internet state & alert user if necessary ...

将警报移出更改处理程序块,并移至上面提到的更改处理程序块和检查当前互联网状态并在必要时提醒用户都可以调用。

Move your alert out of the change handler block and into a method that both the change handler block and the "check current internet state & alert user if necessary" mention above can call.

这篇关于为什么可达性管理器无法检测到Internet?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆