8

我正在努力获得真实的互联网连接状态。我使用了 Apple 的 Reachability,但它只给了我 wifi 连接的状态,即不包括设备通过 wifi 连接(到路由器或热点)的情况,但 wifi 路由器或热点本身没有连接到互联网。通过从 wifi 路由器拉出互联网输入电缆,可以重现这种情况。可达性的通知器ReachableViaWiFi同时返回reachabilityForInternetConnectionReachabilityWithHostName。我非常愿意解决这个问题。我也尝试NSURLConnection过,但这太耗电了,而且我个人不喜欢那种继续发出 URL 请求的解决方案,尽管是在后台线程中。

这是我正在使用的代码(由 SO 研究员提供,但不记得确切的链接)

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil];

    internetReachable = [[Reachability reachabilityForInternetConnection] retain];
    [internetReachable startNotifier];

    // check if a pathway to a random host exists
    hostReachable = [[Reachability reachabilityWithHostName: @"www.google.com"] retain];
    [hostReachable startNotifier];

然后在观察者方法中:

 - (void) checkNetworkStatus:(NSNotification *)notice{

    // called after network status changes

    NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
    switch (internetStatus)

    {
        case NotReachable:
        {
            NSLog(@"The internet is down.");
            self.isInternetReachable = NO;

            break;

        }
        case ReachableViaWiFi:
        {
            NSLog(@"The internet is working via WIFI.");
            self.isInternetReachable = YES;

            break;

        }
        case ReachableViaWWAN:
        {
            NSLog(@"The internet is working via WWAN.");
            self.isInternetReachable = YES;

            break;

        }
    }
    NetworkStatus hostStatus = [hostReachable currentReachabilityStatus];
    switch (hostStatus)

    {
        case NotReachable:
        {
            NSLog(@"A gateway to the host server is down.");
            self.isHostReachable = NO;

            break;

        }
        case ReachableViaWiFi:
        {
            NSLog(@"A gateway to the host server is working via WIFI.");
            self.isHostReachable = YES;

            break;

        }
        case ReachableViaWWAN:
        {
            NSLog(@"A gateway to the host server is working via WWAN.");
            self.isHostReachable = YES;

            break;

        }
}
}
4

3 回答 3

7

根据Reachability,它不仅检查 wifi,还检查 WWAN/3G 和没有互联网访问,为什么你认为它除了 WIFI 不检查?

 typedef enum {

    NotReachable = 0,

    ReachableViaWiFi,

    ReachableViaWWAN

} NetworkStatus;

如果您想检查对特定主机的可达性,那么您可以像这样自己设置主机

Reachability *hostReach = [Reachability reachabilityWithHostName: @"www.google.com"];

NetworkStatus netStatus = [hostReach currentReachabilityStatus];

 switch (netStatus)
    {
        case ReachableViaWWAN:
        {
            NSLog(@"WWAN/3G");
            break;
        }
        case ReachableViaWiFi:
        {
            NSLog(@"WIFI");
            break;
        }
        case NotReachable:
        { 
            NSLog(@"NO Internet");
            break;
        }
}
于 2013-02-28T22:09:22.337 回答
4

见乔丹的回答。Apple 官方的 Reachability.m 中有一个愚蠢的错误。returnValue 的类型应该是“NetworkStatus”而不是“BOOL”:

- (NetworkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags
{
    ...
    NetworkStatus returnValue = NotReachable;
    ...
}

否则,您最终会遭受以下可怕的后果:

  1. 即使蜂窝连接可用,也会报告为不可用。
  2. 如果 Wifi 不可用,如果蜂窝连接可用,则会报告 Wifi 可用。

不敢相信苹果从来没有费心解决这个问题。

(PS新手堆栈溢出并且没有代表支持乔丹)

于 2014-01-28T00:48:02.800 回答
0

即使断开连接,我也收到了 Wifi 标志。Reachability.m 方法中有一个错误:

- (NetworkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags

它使用 BOOL 作为返回值,但它为它分配了具有 3 个值的结构的值:

typedef enum : NSInteger {
    NotReachable = 0,
    ReachableViaWiFi,
    ReachableViaWWAN
} NetworkStatus;

因此,如果 Wifi 或 Cellular 可用,它将 ReachableViaWiFi(因为 BOOL 可以是 0 或 1,但不能是两个)

要修复它,只需更改上面的方法:

BOOL returnValue = NotReachable;

为了这:

int returnValue = NotReachable;

你可以走了。希望能帮助到你。

于 2013-11-07T15:24:45.863 回答