在 CaptiveNetwork 被弃用并且对 Wifi 名称的调用已被阻止后,如何在 iOS9 中获取 Wifi SSID

How to get Wifi SSID in iOS9 after CaptiveNetwork is deprecated and calls for Wifi name are already blocked

直到今天我都使用CaptiveNetwork Interface来显示当前连接的Wifi的名称。 iOS 9 Prerelease 参考已经指出,CaptiveNetwork 方法现在已失效,但它们在开始时仍然有效。

A​​pple 似乎已经在最新版本中阻止了此调用(可能是出于隐私方面的考虑?)。

有没有其他方法获取当前Wifi名称?

直到今天,我都是这样获取SSID的,而你现在只能获取nil:

#import <SystemConfiguration/CaptiveNetwork.h>

NSString *wifiName = nil;  
NSArray *interFaceNames = (__bridge_transfer id)CNCopySupportedInterfaces(); 

for (NSString *name in interFaceNames) { 
    NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)name); 

    if (info[@"SSID"]) { 
        wifiName = info[@"SSID"]; 
    } 
} 

将您的应用程序注册为热点助手。

#import <NetworkExtension/NetworkExtension.h>  

NSArray * networkInterfaces = [NEHotspotHelper supportedNetworkInterfaces];  
NSLog(@"Networks %@",networkInterfaces);  

更新(2015 年 9 月 11 日)

以下强制网络 API 已在最新版本的 iOS 9 中重新启用。

  • CNCopySupportedInterfaces
  • CNCopyCurrentNetworkInfo

更新(2015 年 9 月 16 日)

如果您仍然喜欢使用 NetworkExtension 并且 Apple 允许您添加权利,那么您可以这样做来获取 wifi 信息:

for(NEHotspotNetwork *hotspotNetwork in [NEHotspotHelper supportedNetworkInterfaces]) {
    NSString *ssid = hotspotNetwork.SSID;
    NSString *bssid = hotspotNetwork.BSSID;
    BOOL secure = hotspotNetwork.secure;
    BOOL autoJoined = hotspotNetwork.autoJoined;
    double signalStrength = hotspotNetwork.signalStrength;
}

NetworkExtension 为您提供一些额外信息,如安全、自动加入或信号强度。它还允许您在后台模式下设置凭证到 wifis,当用户扫描周围的 wifis 时。

在 iOS9 的 GM 中,似乎又启用了此功能。事实上,它甚至没有在在线文档中列为已弃用,但是 CaptiveNetwork 头文件确实具有以下内容:

CNCopySupportedInterfaces (void) __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_8, __MAC_NA, __IPHONE_4_1, __IPHONE_9_0, CN_DEPRECATION_NOTICE);

所以,它在 iOS 9 GM 中工作,但不确定多长时间:)

CaptiveNetwork 仍在工作。由于许多请求,Apple 可能已经恢复了 API。

使用CaptiveNetwork我们可以获得WiFi网络的SSID。 它甚至适用于 iOS 10。

#import <SystemConfiguration/CaptiveNetwork.h>

NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)name);

这是输出:

Printing description of info:
{
    BSSID = "5*:**:**:**:**:**";
    SSID = Cisco12814;
    SSIDDATA = <43697363 6f313238 3134>;
}

2017 年 4 月 27 日确认,Captive Network 仍在为 Swift 3.1XCode 8.3

工作

对于Swift > 3.0

func printCurrentWifiInfo() {
  if let interface = CNCopySupportedInterfaces() {
    for i in 0..<CFArrayGetCount(interface) {
      let interfaceName: UnsafeRawPointer = CFArrayGetValueAtIndex(interface, i)
      let rec = unsafeBitCast(interfaceName, to: AnyObject.self)
      if let unsafeInterfaceData = CNCopyCurrentNetworkInfo("\(rec)" as CFString), let interfaceData = unsafeInterfaceData as? [String : AnyObject] {
        // connected wifi
        print("BSSID: \(interfaceData["BSSID"]), SSID: \(interfaceData["SSID"]), SSIDDATA: \(interfaceData["SSIDDATA"])")
      } else {
        // not connected wifi
      }
    }
  }
}

对于Objective-C

NSArray *interFaceNames = (__bridge_transfer id)CNCopySupportedInterfaces();

for (NSString *name in interFaceNames) {
  NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)name);

  NSLog(@"wifi info: bssid: %@, ssid:%@, ssidData: %@", info[@"BSSID"], info[@"SSID"], info[@"SSIDDATA"]);
 }

如前所述,CaptiveNetwork 在 Xcode 8.3 及更高版本上运行良好。以下是 Swift 3Swift 4Objective-C 的代码片段.

Swift 3 & 4

import SystemConfiguration.CaptiveNetwork

internal class SSID {

    class func fetchSSIDInfo() -> [String: Any] {
        var interface = [String: Any]()
        if let interfaces = CNCopySupportedInterfaces() {
            for i in 0..<CFArrayGetCount(interfaces){
                let interfaceName = CFArrayGetValueAtIndex(interfaces, i)
                let rec = unsafeBitCast(interfaceName, to: AnyObject.self)
                guard let unsafeInterfaceData = CNCopyCurrentNetworkInfo("\(rec)" as CFString) else {
                    return interface
                }
                guard let interfaceData = unsafeInterfaceData as? [String: Any] else {
                    return interface
                }
                interface = interfaceData
            }
        }
        return interface
    }

}

Objective-C

#import <SystemConfiguration/CaptiveNetwork.h>

+ (NSDictionary *)fetchSSIDInfo
{
    NSArray *interFaceNames = (__bridge_transfer id)CNCopySupportedInterfaces();
    for (NSString *name in interFaceNames)
    {
        NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)name);
        return info;
    }
    return nil;
}

即使对于 Swift 4.1 和 4.2,abdullahselek 的回答仍然正确。

一个小警告是,现在在 iOS 12 中,您必须转到应用程序项目的功能部分并启用 访问 WiFi 信息 功能。它将向您的项目添加一个权利条目并允许函数调用 CNCopyCurrentNetworkInfo 正常工作。

如果你不这样做,那函数干脆returns nil。运行时不会显示有关缺少权利的错误或警告。

有关详细信息,请参阅下面的 link Apple 文档。

https://developer.apple.com/documentation/systemconfiguration/1614126-cncopycurrentnetworkinfo

CaptiveNetwork 仍在工作。但是你需要添加这个:

com.apple.developer.networking.wifi-info = true inside your Entitlements.plist.

Plus, you need to be Enable the Access WiFi Information in the App ID part in your developer.apple.com portal.

请确保,要清理您的环境,请在启用 App ID 中的选项 "Access WiFi Information" 后生成新的配置文件。

现在应该可以在 iOS 13.3 上使用。我正在使用相关的 Pod 库,该库使用 Objc 中的确切函数并带有 Swift 包装器。

https://github.com/Feghal/FGRoute