我目前正在使用以下内容检查我的应用程序是否可以使用Wi-Fi:
#importstatic 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"(和马特·布朗显然).
首先,修改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连接将声明没有连接.