iPhone Wifi 开启还是关闭?

Posted

技术标签:

【中文标题】iPhone Wifi 开启还是关闭?【英文标题】:iPhone Wifi on or off? 【发布时间】:2012-10-16 01:04:32 【问题描述】:

ios 框架中,如何检查用户是否启用了 Wifi 无线电?请注意,我对通过 Wifi 的可达性不感兴趣,而是对设备是否被用户关闭感兴趣。谢谢。

【问题讨论】:

你的意思是专门针对用户的吗? 见:***.com/questions/1448411/… Ravi 和 Magma,我有一个应用程序,我需要在代码中检查用户是否关闭了 Wifi 设备或它是否处于打开状态。如果我错了,请纠正我,但根据我的理解,可达性提供了您是否可以通过 Wifi 接口访问互联网的信息,而不是关于其开/关状态的信息。 我一句话——你不能。见彼得的回答 我的回答中有一个骇人听闻的解决方案:***.com/questions/29487270/… 【参考方案1】:

基于:http://www.enigmaticape.com/blog/determine-wifi-enabled-ios-one-weird-trick

Wifi 状态可以使用基于 C 的 ifaddress 结构来确定为 ON/OFF:

ifaddrs.h 和

net/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")

【讨论】:

这确实有效!它基于以下出色的分析:enigmaticape.com/blog/… 注意:在我的 iPhone 4s (iOS 8.3) 上,这很遗憾总是返回 NO - 无论 Wi-Fi 的状态如何。 记得在使用完接口后调用 freeifaddrs。【参考方案2】:

正如@magma 评论中提到的,您可能必须使用可达性源代码。 到目前为止,根据我的经验和其他人一直在谈论的内容,没有布尔值可以告诉您用户是否在“设置”中关闭了 Wi-Fi。通过检查设备是否可以访问互联网,您只需推断并得出结论(假设)用户已关闭 Wi-Fi。

【讨论】:

【参考方案3】:

使用可达性是正确的方法。

您无法访问应在 App Store 上发布的应用程序中的直接设置。 这被视为应用程序根本没有理由处理的私人用户领域。

但如果没有更多解释,我并不认为需要找出设置。

这不是应用程序应该感兴趣或担心的。您有网络访问权限,或者您没有网络访问权限。如果没有可用的,那么它的原因并不重要。

您不会问诸如“您没有福特吗?”之类的问题。 “你没有宝马吗?”而不是从一个好的应用程序设计中问“你有车吗?”

Raechability 也与互联网无关。它会告诉您设备理论上是否可以通过 TCP/IP 网络访问。这意味着一些网络通信可用。然后您可以检查什么类型(例如 Wifi 与 3G/LTE)。这正是 Reachability 的用途。

如果您出于某种原因真的想在收音机打开并且它是针对一种企业应用程序的情况下关闭,您可以查看私有框架,导入它们并处理它们未记录的方法,这些方法受制于随任何更新而改变。

对于 Wifi,应该是:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/PrivateFrameworks/MobileWiFi.framework

【讨论】:

当你说“没有理由......根本......”时要小心你的应用程序可能想要有礼貌,并且只在 wifi 上上传分析信息而不用完用户的配额(并非世界上每个人都有无限的计划)。您可能不想通过手机网络下载 500 MB 的可选游戏数据,或者像 Apple 的 AppStore 应用一样,拒绝通过手机连接下载超过一定大小的应用。 另一种您可能关心 WiFi 开启或关闭(特别是与外部实体无关)的情况是在多点连接环境中,打开 wifi 是可选的,但可以改善用户体验可衡量的。 另一个想知道 WiFi 是打开还是关闭的原因是您是否正在监视地理区域。如果打开wifi,进入/退出事件会更加及时和准确。在小区域的情况下,没有 wifi,可能会完全错过该区域,并且不会生成任何事件。在 Wifi 关闭的情况下,您可以选择继续使用 GPS 直接检测区域。 @BradBrighton 我认为必须打开 WiFi 或蓝牙才能使 Multipeer Connectivity 正常工作。 @paranoidcoder 一个或另一个,正确的。在一般情况下,MPC 意味着对于开发者的利益是不透明的。但是,由于带宽较低,如果 BT 开启且 wifi 关闭,则某些配置或数据减少操作可能有意义。【参考方案4】:

iOS 没有公共 API 可以告诉您 Wi-Fi 是打开还是关闭。

但是,您可以使用 SystemConfiguration 框架中提供的公共 API CNCopyCurrentNetworkInfo() 来获取有关当前 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;
    

【讨论】:

【参考方案5】:

Swift 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

Swift 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

【讨论】:

【参考方案6】:

PrivateFrameworks 在 sdk 中不可用,也不可供任何企业开发人员使用。

如果我们知道您想要实现什么,我知道 wifi 无线电功率状态,我们可能会建议一个替代解决方案,但从苹果公司如何处理他们向开发人员公开的内容来看,我认为这不会直接成为可能。

使用可达性,您可以确定 wifi 是否打开,但要知道 wifi 是否关闭,请掷硬币。

【讨论】:

以上是关于iPhone Wifi 开启还是关闭?的主要内容,如果未能解决你的问题,请参考以下文章

iphone控制中心关闭蓝牙和WiFi,为啥不能彻底关闭,还要到系统关闭?

iPhone7蓝牙搜不到设备怎么办?iPhone7蓝牙连不上怎么办

iPhone无法通过WiFi连接到本地HTTP服务器

iPhone怎么查看是不是连接过的wifi?

iPhone12控制中心关闭无线局域网和蓝牙是真的关闭吗

如何开启/关闭iPhone相机闪光灯?