Xcode10/iOS12 获取 WiFi 信息

引言:

在一些特定业务场景下,我们需要获取 iOS 设备所连接的 WiFi 的信息,比如 WiFi 的 SSID(即 WiFi 的名称),WiFi 的 BSSID(即 WiFi 的路由器的 Mac 地址)等,相应的代码也很简单。


# 一. 常规获取代码


// 获取 wifi
#import <SystemConfiguration/CaptiveNetwork.h>
#import <NetworkExtension/NetworkExtension.h>

// 获取 wifi 信息
- (NSString *)wifiSSID {
    
    CFArrayRef wifis = CNCopySupportedInterfaces();
    if (wifis == nil || CFArrayGetCount(wifis) == 0) {
        return nil;
    }
    
    NSArray *interfaces = (__bridge_transfer id)wifis;
    NSDictionary *info = [NSDictionary dictionary];
    for (NSString *name in interfaces) {
        info = (__bridge_transfer NSDictionary *)CNCopyCurrentNetworkInfo((__bridge CFStringRef)name);
    }
    if (info == nil) {
        return nil;
    }
    
    NSString *ssid = info[@"SSID"];
    NSString *bssid = info[@"BSSID"];
    NSLog(@"wifi name: %@ - %@", ssid, bssid);
    return ssid;
}

Xcode 10(iOS 12)之前,上述代码可以正常运行取到结果,但当升级到 Xcode 10 后编译工程在 iOS 12 上运行时,同样的代码却无法取得 WiFi 的信息。通过断点调试发现CNCopyCurrentNetworkInfo(...) 函数总是返回 nil,查阅官方 API 文档,发现该函数的描述多了一条重要提示,如下图红框内容:

大致意思是:

在iOS 12+中使用此方法需要在Xcode中为应用授权获取WiFi信息的能力。授权后,Xcode会自动在App ID和应用的权限列表中增加获取WiFi信息的权限。


# 二. Xcode10配置

首先更改 证书,添加 Access WiFi Information 选项:

在 Xcode 工程中授权获取 WiFi 信息的能力,开启路径为:Xcode -> [Project Name] -> Targets -> [Target Name] -> Capabilities -> Access WiFi Information -> ON,如下图:

设置完毕后,我们可以发现在工程的 .entitlements 文件会多了一对键值:

Access WiFi Information => YES

至此,我们就可以正常在 iOS 12+ 中获取 WiFi 的信息了。