【问题标题】:iOS Reachability reports no WiFi, when WiFi is active当 WiFi 处于活动状态时,iOS 可达性报告没有 WiFi
【发布时间】:2016-02-25 14:12:55
【问题描述】:

我正在使用来自 Apple 的 Reachability class 来检测影响我的应用程序功能的网络事件。这是一个使用 setKeepAliveTimeout 的 voip 应用程序,因此每约 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 似乎已连接。但是,由于错误值,我已经触发了一个事件,并且应用程序关闭了与服务器的连接,认为没有 wi-fi。

做了一些研究,我在 Reachability.m 文件的自述文件中发现了这个(由 Apple 提供)

默认情况下,应用程序使用 www.apple.com 作为其远程主机。您可以通过修改 -viewDidLoad 中 remoteHostName 变量的值来更改它在 APLViewController.m 中使用的主机。

重要提示:可达性必须先使用 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 类中有一个方法似乎是从 Apple 的演示中使用的。

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

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

    return NO;
}

为什么需要connectionRequired?可以用来解决问题吗?

【问题讨论】:

标签: ios reachability


【解决方案1】:

为了节省电池电量,iOS 会在网络硬件不活跃时关闭它。这意味着关闭 WiFi 和蜂窝无线电。在这种情况下,Reachability 将无法报告完整的结果,因为它无法在不重新打开所有内容的情况下检查情况。这就是kSCNetworkReachabilityFlagsConnectionRequired 的用途——告诉您需要建立连接以唤醒硬件备份。

您所看到的可能是手机解锁时唤醒的东西(您的应用程序或其他具有后台权限的应用程序),因此一切都唤醒了,您立即看到错误,但随后 WiFi 连接并再次连接。

您需要处理可达性,就好像它可以告诉您“绝对可达”或“绝对不可达”,但也可以告诉您“情况未知”。你需要决定在未知的情况下你要做什么。如果您立即进行网络连接,那么您将比正常情况下更快地耗尽电池。另一种选择可能只是等待网络因其他原因被唤醒。这完全取决于您。

【讨论】:

    【解决方案2】:

    应该使用主机名而不是显式地址来创建可达性。 DNS系统的全部意义在于主机的地址有时会发生变化。直接链接到名称服务器应该在这方面提供一些安全性,但这不是它应该如何工作的。

    可达性通常是最好的猜测,而不是一成不变的。唯一确定的方法是实际尝试。所需的连接与此有关,因为它是设备说“一切正常,我只是没有尝试真正连接”。

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

    【讨论】:

    • 示例代码到底是什么?我的意思是解雇你的refresh 并检查回复
    猜你喜欢
    • 2015-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多