在 iOS 框架中,如何检查用户是否启用了 Wifi 无线电?请注意,我对通过 Wifi 的可达性不感兴趣,而是对设备是否被用户关闭感兴趣。谢谢。
6 回答
基于:http ://www.enigmaticape.com/blog/determine-wifi-enabled-ios-one-weird-trick
Wifi 状态可以使用基于 C 的 ifaddress 结构确定为 ON/OFF:
ifaddrs.h 和
净/if.h
[代码来源:未知。]
- (BOOL) isWiFiEnabled {
NSCountedSet * cset = [NSCountedSet new];
struct ifaddrs *interfaces;
if( ! getifaddrs(&interfaces) ) {
for( struct ifaddrs *interface = interfaces; interface; interface = interface->ifa_next) {
if ( (interface->ifa_flags & IFF_UP) == IFF_UP ) {
[cset addObject:[NSString stringWithUTF8String:interface->ifa_name]];
}
}
}
return [cset countForObject:@"awdl0"] > 1 ? YES : NO;
}
Swift 3 版本(需要桥接头#include <ifaddrs.h>
):
func isWifiEnabled() -> Bool {
var addresses = [String]()
var ifaddr : UnsafeMutablePointer<ifaddrs>?
guard getifaddrs(&ifaddr) == 0 else { return false }
guard let firstAddr = ifaddr else { return false }
for ptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
addresses.append(String(cString: ptr.pointee.ifa_name))
}
freeifaddrs(ifaddr)
return addresses.contains("awdl0")
}
正如@magma 评论中提到的,您可能必须使用可达性源代码。到目前为止,根据我的经验和其他人一直在谈论的内容,没有布尔值可以告诉您用户是否在“设置”中关闭了 Wi-Fi。通过检查设备是否可以访问互联网,您只需推断并得出结论(假设)用户已关闭 Wi-Fi。
使用可达性是正确的方法。
您无法访问应在 App Store 上发布的应用程序中的直接设置。这被认为是应用程序根本没有理由处理的私人用户领域。
但如果没有更多解释,我并不认为需要找出设置。
这不是应用程序应该感兴趣或担心的事情。您有网络访问权限,或者您没有网络访问权限。如果没有可用的,那么它的原因并不重要。
你不会问“你没有福特吗?”这样的问题。“你没有宝马吗?” 而是从一个好的应用程序设计中问“你有车吗?”
Raechability 也与 Internet 无关。它会告诉您设备理论上是否可以通过 TCP/IP 网络访问。这意味着一些网络通信可用。然后您可以检查什么类型(例如 Wifi 与 3G/LTE)。这正是 Reachability 的用途。
如果您出于某种原因真的想在收音机打开并且它是一种企业应用程序的情况下关闭,您可以查看私有框架,导入它们并处理它们的未记录方法,这些方法可能会随任何变化而发生变化更新。
对于 Wifi,它应该是:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/PrivateFrameworks/MobileWiFi.framework
iOS 没有公共 API 可以告诉您 Wi-Fi 是打开还是关闭。
但是,您可以使用 SystemConfiguration 框架中提供的公共 APICNCopyCurrentNetworkInfo()
来获取有关当前 Wi-Fi 网络的信息。这不会告诉您 Wi-Fi 是打开还是关闭,而是告诉您设备是否已加入 Wi-Fi 网络。也许这足以满足您的目的。
另请注意,此 API 在 Simulator 中不起作用,因为CNCopySupportedInterfaces()
总是返回 NULL。
#include <SystemConfiguration/CaptiveNetwork.h>
BOOL hasWiFiNetwork = NO;
NSArray *interfaces = CFBridgingRelease(CNCopySupportedInterfaces());
for (NSString *interface in interfaces) {
NSDictionary *networkInfo = CFBridgingRelease(CNCopyCurrentNetworkInfo((__bridge CFStringRef)(interface)));
if (networkInfo != NULL) {
hasWiFiNetwork = YES;
break;
}
}
斯威夫特 2.3 版本
func isWifiEnabled() -> Bool {
var addresses = [String]()
var ifaddr : UnsafeMutablePointer<ifaddrs> = nil
guard getifaddrs(&ifaddr) == 0 else { return false }
var ptr = ifaddr
while ptr != nil { defer { ptr = ptr.memory.ifa_next }
addresses.append(String.fromCString(ptr.memory.ifa_name)!)
}
var counts:[String:Int] = [:]
for item in addresses {
counts[item] = (counts[item] ?? 0) + 1
}
freeifaddrs(ifaddr)
return counts["awdl0"] > 1 ? true : false
}
斯威夫特 4.0 版本
func isWifiEnabled() -> Bool {
var addresses = [String]()
var ifaddr : UnsafeMutablePointer<ifaddrs>?
guard getifaddrs(&ifaddr) == 0 else { return false }
guard let firstAddr = ifaddr else { return false }
for ptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
addresses.append(String(cString: ptr.pointee.ifa_name))
}
var counts:[String:Int] = [:]
for item in addresses {
counts[item] = (counts[item] ?? 0) + 1
}
freeifaddrs(ifaddr)
guard let count = counts["awdl0"] else { return false }
return count > 1
}
PrivateFrameworks 在 sdk 中不可用,也不可供任何企业开发人员使用。
如果我们知道您想要实现什么,我知道 wifi 无线电功率状态,我们可能会建议一个替代解决方案,但从苹果公司如何处理他们向开发人员公开的内容,我认为这不会直接成为可能。
使用可达性,您可以确定 wifi 是否打开,但要知道 wifi 是否关闭,请掷硬币。