iOS可达性报告显示没有WiFi,但WiFi已经启用

6

我正在使用苹果提供的Reachability类来检测对我的应用程序功能有影响的网络事件。这是一个Voip应用程序,它使用setKeepAliveTimeout,因此每10分钟左右会被唤醒以读取网络状态,并决定是否需要刷新连接。

BOOL res = [app setKeepAliveTimeout:600 handler:^{        
      [[WIFI instance] isWifiConnected];
      [[AClass an_instance] refresh];
  }
}];

所以每10分钟调用isWifiConnected函数,应用程序再次读取网络状态。
- (BOOL) isWifiConnected {

    self.wifiReach = [Reachability reachabilityForLocalWiFi];
    NetworkStatus wifiStatus = [self.wifiReach currentReachabilityStatus];

    switch (wifiStatus) {
        case NotReachable: {
            m_wifiConnected = NO;  
            LOG(@"NetStatus:NotReachable");
            break;
        }
        case ReachableViaWiFi: {
            m_wifiConnected = YES;   
            m_wwanConnected = NO;
            LOG(@"NetStatus:ReachableViaWiFi");
            break;
        }
    }
    return m_wifiConnected;
}

尽管设备上有WiFi,但通话返回false,即没有WiFi,而且网络状态为NotReachable。然而,在非常短的时间间隔后,可达性回调再次被调用,wifi似乎已经连接。然而,由于错误值,我已经触发了一个事件,并且应用程序关闭了与服务器的连接,认为没有wifi。
在Reachability.m文件的Readme文件中(由Apple提供),我找到了以下内容:
默认情况下,应用程序使用www.apple.com作为其远程主机。您可以通过修改-viewDidLoad中的remoteHostName变量的值来更改它使用的主机名。
重要提示:在确定主机的可达性之前,可达性必须使用DNS解析主机名,这可能需要一些时间在某些网络连接上。因此,API将返回NotReachable,直到名称解析完成。在某些网络上,此延迟可能在界面上可见。
这可能是问题吗?DNS查找的延迟?还是我需要改进我的代码?
当我初始化应用程序时,我调用了这个。
self.hostReach = [Reachability reachabilityWithHostName: @"www.apple.com"];

如果我使用这样的IP地址是正确的吗?
self.hostReach = [Reachability reachabilityWithHostName: @"1.2.3.4"];

使用公共IP是否安全?例如,“17.178.96.59”是对apple.com进行nslookup的结果。

在Reachability类中有一种方法,似乎是从苹果演示中使用的。

- (BOOL)connectionRequired
{
    NSAssert(_reachabilityRef != NULL, @"connectionRequired called with NULL reachabilityRef");
    SCNetworkReachabilityFlags flags;

    if (SCNetworkReachabilityGetFlags(_reachabilityRef, &flags))
    {
        return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
    }

    return NO;
}

为什么需要connectionRequired?它能解决问题吗?

为什么您要每隔10分钟调用一次方法,而不使用https://github.com/ashleymills/Reachability.swift呢? - Parth Dabhi
我需要大约每10分钟触发一次SIP注册事件。 - cateof
2个回答

2
为了保持电池电量,iOS会在网络硬件不被积极使用时关闭它。这意味着关闭WiFi和移动数据。在这种情况下,可达性将无法报告完整的结果,因为它无法在不重新打开一切的情况下检查情况。这就是“kSCNetworkReachabilityFlagsConnectionRequired”的作用-告诉您需要建立连接以唤醒硬件。
您看到的可能是手机解锁时某个应用(您的应用或其他具有后台权限的应用)正在唤醒,因此一切都被唤醒,您立即看到错误,但然后WiFi连接,您再次连接。
您需要处理可达性,就好像它可以告诉您“绝对可达”或“绝对不可达”,但也“情况未知”。您需要决定在未知情况下要做什么。如果立即进行网络连接,那么电池将比正常更快地耗尽。另一个选择可能只是等待网络因其他原因被唤醒。这真的取决于您。

1

应该使用主机名而不是显式地址创建可达性。DNS系统的整个意义在于,主机的地址有时会更改。直接链接到名称服务器应该在这方面提供一些安全保障,但这不是它应该工作的方式。

可达性通常是最佳猜测,而不是硬性规定。确保的唯一方法是实际尝试连接。所需的连接与此相关,因为设备会说“一切看起来都很好,我只是还没有真正尝试连接”。

因此,可以在不检查可达性状态的情况下触发保持活动状态,并使用请求的结果来决定是否存在错误。如果需要确保,发送实际请求并查看实际结果。


示例代码是用来做什么的?我的意思是执行“刷新”操作并检查响应。 - Wain

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接