当前位置:  开发笔记 > IOS > 正文

如何使用iPhone SDK检查本地Wi-Fi(不仅仅是蜂窝连接)?

如何解决《如何使用iPhoneSDK检查本地Wi-Fi(不仅仅是蜂窝连接)?》经验,为你挑选了1个好方法。

我目前正在使用以下内容检查我的应用程序是否可以使用Wi-Fi:

#import 
static inline BOOL addressReachable(const struct sockaddr_in *hostAddress);

BOOL localWiFiAvailable()
{
    struct sockaddr_in localWifiAddress;
    bzero(&localWifiAddress, sizeof(localWifiAddress));
    localWifiAddress.sin_len = sizeof(localWifiAddress);
    localWifiAddress.sin_family = AF_INET;
    // IN_LINKLOCALNETNUM is defined in  as 169.254.0.0
    localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);

    return addressReachable(&localWifiAddress);
}

static inline BOOL addressReachable(const struct sockaddr_in *hostAddress)
{
    const SCNetworkReachabilityRef target =
          SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault,
                                                 (const struct sockaddr *)hostAddress);
    if (target != NULL)
    {
        SCNetworkReachabilityFlags flags = 0;
        const BOOL reachable = SCNetworkReachabilityGetFlags(target, &flags);
        CFRelease(target);
        return reachable && (flags & kSCNetworkFlagsReachable);
    }
    return NO;
}

然而,当iPhone仅连接到蜂窝网络但不连接到Wi-Fi网络时,这不会返回NO.有谁知道如何解决这一问题?

编辑

所以这就是我最终使用的:

#import  // For AF_INET, etc.
#import  // For getifaddrs()
#import  // For IFF_LOOPBACK

BOOL localWiFiAvailable()
{
    struct ifaddrs *addresses;
    struct ifaddrs *cursor;
    BOOL wiFiAvailable = NO;
    if (getifaddrs(&addresses) != 0) return NO;

    cursor = addresses;
    while (cursor != NULL) {
        if (cursor -> ifa_addr -> sa_family == AF_INET
            && !(cursor -> ifa_flags & IFF_LOOPBACK)) // Ignore the loopback address
        {
            // Check for WiFi adapter
            if (strcmp(cursor -> ifa_name, "en0") == 0) {
                wiFiAvailable = YES;
                break;
            }
        }
        cursor = cursor -> ifa_next;
    }

    freeifaddrs(addresses);
    return wiFiAvailable;
}

谢谢"unforgiven"(和马特·布朗显然).



1> Massimo Cafa..:

首先,修改addressReachable方法.代替

return reachable && (flags & kSCNetworkFlagsReachable);

添加以下内容:

BOOL isReachable = ((flags & kSCNetworkFlagsReachable) != 0);
BOOL needsConnection = ((flags & kSCNetworkFlagsConnectionRequired) != 0);
return (isReachable && !needsConnection) ? YES : NO;

这是检查可用连接的正确方法.现在,如果您想清楚地区分蜂窝和wifi,请修改您的方法以返回int并使用以下内容

BOOL isReachable = ((flags & kSCNetworkFlagsReachable) != 0);
BOOL needsConnection = ((flags & kSCNetworkFlagsConnectionRequired) != 0);

if(isReachable && !needsConnection) // connection is available 
{

   // determine what type of connection is available
   BOOL isCellularConnection = ((flags & kSCNetworkReachabilityFlagsIsWWAN) != 0);
   NSString *wifiIPAddress = [self getWiFiIPAddress];

   if(isCellularConnection) 
        return 1; // cellular connection available

   if(wifiIPAddress)
       return 2; // wifi connection available
}
else
   return 0; // no connection at all

getWiFiIPAddress方法由Matt Brown提供,可以在这里找到.

还有一件事.kSCNetworkReachabilityFlagsIsDirect标志可以告诉您网络流量是通过网关还是直接到达.在某些情况下,这可能会有所帮助.

代码在设备上正常运行.在模拟器上,当您通过以太网电缆连接时,它将声明您通过wifi连接,并且如果您通过wifi连接将声明没有连接.

推荐阅读
mobiledu2402851173
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有