iOS13 获取WiFi信息

4,015 阅读2分钟

最近收到了苹果开发者发来的一封邮件:大致内容就是从iOS13开始,将对app中通过CNCopyCurrentNetworkInfo API来获取设备当前所连接的wifi 的功能进行限制

As we announced at WWDC19, we're making changes to further protect user privacy and prevent unauthorized location tracking. Starting with iOS 13, the CNCopyCurrentNetworkInfo API will no longer return valid Wi-Fi SSID and BSSID information. Instead, the information returned by default will be: 

SSID: “Wi-Fi” or “WLAN” (“WLAN" will be returned for the China SKU)
BSSID: "00:00:00:00:00:00" 

If your app is using this API, we encourage you to adopt alternative approaches that don’t require Wi-Fi or network information. Valid SSID and BSSID information from CNCopyCurrentNetworkInfo will still be provided to VPN apps, apps that have used NEHotspotConfiguration to configure the current Wi-Fi network, and apps that have obtained permission to access user location through Location Services. 

Test your app on the latest iOS 13 beta to make sure it works properly. If your app requires valid Wi-Fi SSID and BSSID information to function, you can do the following:
For accessory setup apps, use the NEHotSpotConfiguration API, which now has the option to pass a prefix of the SSID hotspot your app expects to connect to.
For other types of apps, use the CoreLocation API to request the user’s consent to access location information.

Learn more by reading the updated documentation or viewing the the Advances in Networking session video from WWDC19. You can also submit a TSI for code-level support. 

Best regards, 
Apple Developer Relations

从 iOS 4.1 开始,Apple 就提供了「CNCopyCurrentNetworkInfo」这项函数,调用时将会得到 SSID 与 BSSID; iOS 12 开始,调用该函数将默认返回 nil,需要在 Xcode 项目中开启「Access WiFi Information」后才会返回正确的值。这个功能需要在开发者页面的 App IDs 中激活才能使用。 而在 iOS 13 中,使用这项函数的条件将变得更为严格。根据 WWDC19 Session 713(developer.apple.com/documentati… iOS 13 中除了开启「Access WiFi Information」以外,App 还需要符合下列三项条件中的至少一项才会返回正确的 CNCopyCurrentNetworkInfo 函数值,否则仍然会返回 nil :

+ (nullable NSString *)getBSSID{
    if (@available(iOS 13.0, *)) {
        //用户明确拒绝,可以弹窗提示用户到设置中手动打开权限
        if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) {
            NSLog(@"User has explicitly denied authorization for this application, or location services are disabled in Settings.");
            //使用下面接口可以打开当前应用的设置页面
            //[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
            return nil;
        }
        CLLocationManager* cllocation = [[CLLocationManager alloc] init];
        if(![CLLocationManager locationServicesEnabled] || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined){
            //弹框提示用户是否开启位置权限
            [cllocation requestWhenInUseAuthorization];
            usleep(500);
            //递归等待用户选选择
            return [self getBSSID];
        }
    }
    NSString *ssid = nil;
    NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
    if (ifs.count == 0) {
        return nil;
    }
    for (NSString *ifnam in ifs) {
        NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
        if (info[@"BSSID"]) {
            ssid = info[@"BSSID"];
        }
    }
    return ssid;
}


打印结果

2019-12-23 17:04:45.337331+0800 Device[20067:3373918] network info -> {
    BSSID = "94:28:2e:7b:89:e2";
    SSID = "SM_08";
    SSIDDATA = {length = 5, bytes = 0x534d5f3038};
}