如何使用CaptiveNetwork获取当前WiFi热点名称

26

我需要获取当前连接的Wi-Fi热点名称,例如"BT OpenZone"

有人告诉我可以使用CaptiveNetwork库中的CNCopyCurrentNetworkInfo来实现。

目前我的代码:

#import <SystemConfiguration/CaptiveNetwork.h>
...

// Get the dictionary containing the captive network infomation
CFDictionaryRef captiveNtwrkDict = CNCopyCurrentNetworkInfo(kCNNetworkInfoKeySSID);

// Get the count of the key value pairs to test if it has worked
int count = CFDictionaryGetCount(captiveNtwrkDict);
NSLog(@"Count of dict:%d",count);
当代码在WiFi热点设备上运行时,captiveNtwrkDict是空的。 有人成功使其工作吗?我找不到关于CaptiveNetworks的文档或示例代码,任何帮助都将不胜感激。
4个回答

27
您需要找出可用的网络,然后将它们传递给CNCopyCurrentNetworkInfo。例如:
CFArrayRef myArray = CNCopySupportedInterfaces();
CFDictionaryRef myDict = CNCopyCurrentNetworkInfo(CFArrayGetValueAtIndex(myArray, 0));

你可以使用获取的字典(myDict)中的kCNNetworkInfoKeySSID键来查找SSID。不要忘记适当释放/管理内存。


2
请问您能否将整个函数添加进去?我已经导入了cnnetwork并添加了这段代码,但是我的应用程序在第二行崩溃了,出现了EXC_BAD_ACCESS错误。 - Mrunal
2
我也遇到了崩溃的问题,但我不知道如何解决。在我的情况下,myArray的值为nil,我从CNCopySupportedInterface()中没有得到任何值。 - Anurag Soni

24

iOS 12,Swift 4.2更新

您必须在功能选项中启用“访问WiFi信息”。

重要提示 要在 iOS 12 及更高版本中使用此功能,请在 Xcode 中为您的应用程序启用“访问WiFi信息”功能。当您启用此功能时,Xcode 会自动向您的权限文件和应用 ID 添加“访问WiFi信息”权限。 文档链接

Swift4.2

public class SSID {
    class func fetchSSIDInfo() -> String {
        var currentSSID = ""
        if let interfaces = CNCopySupportedInterfaces() {
            for i in 0..<CFArrayGetCount(interfaces) {
                let interfaceName: UnsafeRawPointer = CFArrayGetValueAtIndex(interfaces, i)
                let rec = unsafeBitCast(interfaceName, to: AnyObject.self)
                let unsafeInterfaceData = CNCopyCurrentNetworkInfo("\(rec)" as CFString)
                if let interfaceData = unsafeInterfaceData as? [String: AnyObject] {
                    currentSSID = interfaceData["SSID"] as! String
                    let BSSID = interfaceData["BSSID"] as! String
                    let SSIDDATA = interfaceData["SSIDDATA"]
                    debugPrint("ssid=\(currentSSID), BSSID=\(BSSID), SSIDDATA=\(SSIDDATA)")
                }
            }
        }
        return currentSSID
    }
}

iOS 10更新内容

iOS 10中不再弃用CNCopySupportedInterfaces。 (API参考)

你需要导入SystemConfiguration/CaptiveNetwork.h 并将SystemConfiguration.framework添加到您的目标链接库(在构建阶段下)。

以下是Swift代码片段(RikiRiocma的回答):

import Foundation
import SystemConfiguration.CaptiveNetwork

public class SSID {
    class func fetchSSIDInfo() ->  String {
        var currentSSID = ""
        if let interfaces:CFArray! = CNCopySupportedInterfaces() {
            for i in 0..<CFArrayGetCount(interfaces){
                let interfaceName: UnsafePointer<Void> = CFArrayGetValueAtIndex(interfaces, i)
                let rec = unsafeBitCast(interfaceName, AnyObject.self)
                let unsafeInterfaceData = CNCopyCurrentNetworkInfo("\(rec)")
                if unsafeInterfaceData != nil {
                    let interfaceData = unsafeInterfaceData! as Dictionary!
                    currentSSID = interfaceData["SSID"] as! String
                }
            }
        }
    return currentSSID
    }
}

(重要提示: 在模拟器上,CNCopySupportedInterfaces 返回 nil.)

对于 Objective-c,请参见Esad的回答(此处和下面)

+ (NSString *)GetCurrentWifiHotSpotName {    
    NSString *wifiName = nil;
    NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
    for (NSString *ifnam in ifs) {
        NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
        if (info[@"SSID"]) {
            wifiName = info[@"SSID"];
        }
    }
    return wifiName;
}

iOS 9更新

iOS 9中弃用了Captive Network。(来源

*iOS 10中不再弃用,请参见上文。

建议使用NEHotspotHelper。(来源

您需要发送电子邮件至networkextension@apple.com并请求授权。(来源

示例代码(非本人代码。请参见Pablo A的答案):

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;
}

附注:是的,在iOS 9中,他们废弃了CNCopySupportedInterfaces,并在iOS 10中扭转了立场。我与一位苹果网络工程师交谈过,这种扭转是在很多人在Apple开发者论坛上提交Radars并发表意见后出现的。


感谢您的详细回复,NEHotspotHelper代码在Swift 3上无法工作。 - Muhammad Faizan Khatri
在 Swift 代码中,我们需要添加 release/retain 吗? - mKane

8

易于使用的代码片段(方法):

  • Add SystemConfiguration.framework

  • import < SystemConfiguration/CaptiveNetwork.h>

  • use the below method

    + (NSString *)GetCurrentWifiHotSpotName {
    
        NSString *wifiName = nil;
        NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
        for (NSString *ifnam in ifs) {
            NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
    
            NSLog(@"info:%@",info);
    
            if (info[@"SSID"]) {
                wifiName = info[@"SSID"];
            }
        }
        return wifiName;
    }
    

你的方法非常有效。 我们能否通过自己的应用禁用/启用WiFi? - Rahul Vyas
我们可以启用/禁用WiFi吗? - Rahul Vyas
如果您的应用程序不是针对应用商店的,您可以通过在Springboard中挂钩SBWiFiManager类来实现。了解更多信息,请访问https://dev59.com/VnDYa4cB1Zd3GeqPDK8E#22590416。 - Durai Amuthan.H
最好使用苹果公司定义的键名而不是硬编码的值。kCNNetworkInfoKeySSID、kCNNetworkInfoKeyBSSID、kCNNetworkInfoKeySSIDData。 - spfursich
@DuraiAmuthan.H它是否提供连接到我的WiFi的设备详细信息?我想获取连接到WiFi路由器的MAC地址,设备名称等,并在iPhone应用程序中显示这些详细信息。 - Nirmit Dagly
显示剩余5条评论

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接