15

我正在尝试使用此代码获取 SSID

import Foundation
import SystemConfiguration.CaptiveNetwork

public class SSID {
    class func getSSID() -> String{
        var currentSSID = ""
        let interfaces = CNCopySupportedInterfaces()
        if interfaces != nil {
            let interfacesArray = interfaces.takeRetainedValue() as [String : AnyObject]
            if interfacesArray.count > 0 {
                let interfaceName = interfacesArray[0] as String
                let unsafeInterfaceData = CNCopyCurrentNetworkInfo(interfaceName)
                if unsafeInterfaceData != nil {
                    let interfaceData = unsafeInterfaceData.takeRetainedValue() as Dictionary!
                    currentSSID = interfaceData[kCNNetworkInfoKeySSID] as! String
                    let ssiddata = NSString(data:interfaceData[kCNNetworkInfoKeySSIDData]! as! NSData, encoding:NSUTF8StringEncoding) as! String
                    // ssid data from hex
                    print(ssiddata)
                }
            }
        }
        return currentSSID
    }
}

但是在这一行出现错误 let interfacesArray = interfaces.takeRetainedValue() as [String : AnyObject]

错误是

Value of type 'CFArray?' has no member 'takeRetainedValue'

谢谢你的帮助

4

10 回答 10

27

这可能会对您有所帮助(在 Swift 2 上测试):

import Foundation
import SystemConfiguration.CaptiveNetwork

public class SSID {
    class func fetchSSIDInfo() -> String {
        var currentSSID = ""
        if let interfaces = 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
    }
}

我从 Ray Wenderlich 的网站上获取并修改了代码(曾经在这里: Retrieve SSID in iOS9但现在特定线程已从网站中删除)

iOS 12

您必须启用从功能访问 WiFi 信息。

重要 要在 iOS 12 及更高版本中使用此功能,请在 Xcode 中为您的应用启用访问 WiFi 信息功能。当您启用此功能时,Xcode 会自动将 Access WiFi Information 权利添加到您的权利文件和 App ID 中。文档链接

斯威夫特4.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"] as! String
                    debugPrint("ssid=\(currentSSID), BSSID=\(BSSID), SSIDDATA=\(SSIDDATA)")
                }
            }
        }
        return currentSSID
    }
}
于 2015-09-24T17:40:32.540 回答
14

这是我的解决方案 Swift 3 iOS 10,它适用于Xcode 8

import Foundation

import SystemConfiguration.CaptiveNetwork

class network : NSObject {

    func getSSID() -> String? {

        let interfaces = CNCopySupportedInterfaces()
        if interfaces == nil {
            return nil
        }

        let interfacesArray = interfaces as! [String]
        if interfacesArray.count <= 0 {
            return nil
        }

        let interfaceName = interfacesArray[0] as String
        let unsafeInterfaceData =     CNCopyCurrentNetworkInfo(interfaceName as CFString)
        if unsafeInterfaceData == nil {
            return nil
        }

        let interfaceData = unsafeInterfaceData as! Dictionary <String,AnyObject>

        return interfaceData["SSID"] as? String
    }

}

要使用它:

let wifiName = network().getSSID()

    guard wifiName != nil else {

        //// TODO: Alert -----
        print("no wifi name")

        return
    }


    print("my network name is: \(wifiName!)")

PS:注意它不适用于模拟器

于 2016-09-18T08:13:30.970 回答
8

目前提出的所有解决方案似乎都相当复杂,带有丑陋的不安全演员表。

我能够制作出如此简洁的解决方案(根本没有黑魔法):

import Foundation
import SystemConfiguration.CaptiveNetwork

func getSSID() -> String? {
    var ssid: String?
    if let interfaces = CNCopySupportedInterfaces() as NSArray? {
        for interface in interfaces {
            if let interfaceInfo = CNCopyCurrentNetworkInfo(interface as! CFString) as NSDictionary? {
                ssid = interfaceInfo[kCNNetworkInfoKeySSID as String] as? String
                break
            }
        }
    }
    return ssid
}
于 2016-06-16T10:25:51.560 回答
5

在 Swift 3 中(在真实设备和模拟器中工作):

import SystemConfiguration.CaptiveNetwork

internal class SSID {
    class func fetchSSIDInfo() ->  String {
        var currentSSID = ""
        if let interfaces:CFArray = 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 unsafeInterfaceData != nil {

                    let interfaceData = unsafeInterfaceData! as Dictionary!
                    currentSSID = ((interfaceData as? [String : AnyObject])?["SSID"])! as! String

                }
            }
        }
        return currentSSID
    }
}

用法:

SSID.fetchSSIDInfo()

//will return "" if no connected wifi or running in simulator 
于 2016-10-11T19:21:42.730 回答
2

斯威夫特 4 版本

import SystemConfiguration.CaptiveNetwork


func getSSID() -> String? {
    guard let interface = (CNCopySupportedInterfaces() as? [String])?.first,
        let unsafeInterfaceData = CNCopyCurrentNetworkInfo(interface as CFString) as? [String: Any],
        let ssid = unsafeInterfaceData["SSID"] as? String else{
            return nil
    }
    return ssid
}
于 2018-07-24T13:33:11.867 回答
1

在 swift 2 中,您不必调用takeRetainedValue.

将代码替换interfaces.takeRetainedValue() as [String : AnyObject]Array(arrayLiteral: interfaces).

还记得把代码interfacesArray[0] as String改成String(interfacesArray[0]).

完整代码:</p>

public class SSID {
class func getSSID() -> String{
    var currentSSID = ""
    let interfaces = CNCopySupportedInterfaces()
    if interfaces != nil {
        let interfacesArray = Array(arrayLiteral: interfaces)
        if interfacesArray.count > 0 {
            let interfaceName =  String(interfacesArray[0])
            let unsafeInterfaceData = CNCopyCurrentNetworkInfo(interfaceName)
            if unsafeInterfaceData != nil {
                let interfaceData = unsafeInterfaceData.takeRetainedValue() as Dictionary!
                currentSSID = interfaceData[kCNNetworkInfoKeySSID] as! String
                let ssiddata = NSString(data:interfaceData[kCNNetworkInfoKeySSIDData]! as! NSData, encoding:NSUTF8StringEncoding) as! String
                // ssid data from hex
                print(ssiddata)
            }
        }
    }
    return currentSSID
}

}

于 2015-09-19T05:25:42.623 回答
1

在 Swift 中获取 WiFi 网络 SSID 和 BSSID

SystemConfiguration我已经使用该框架看到了这个非常流行的问题的很多版本。通读这个答案列表,我发现它们无处不在。不安全的位转换,魔术字符串,奇怪的强制。任何时候 API 返回CFArrayCFDictionary使用免费桥接来获取NS{Array,Dictionary}. 它允许您避免CoreFoundation. 此外,您应该使用标题中为 SSID 和 BSSID 字典值定义的常量。这里绝对不需要 Unsafe 类型,所有的数据类型都是定义良好的。也就是说,此代码的 CaptiveNetwork 版本在 iOS 14 中已弃用,建议您改用该NetworkExtension框架。

NE热点网络

import NetworkExtension

NEHotspotNetwork.fetchCurrent { hotspotNetwork in
    if let ssid = hotspotNetwork?.ssid {
        print(ssid)
    }
}

已弃用 - CaptiveNetwork 方法

import SystemConfiguration.CaptiveNetwork

func getWiFiNetwork() -> (ssid: String, bssid: String)?
{
    var wifiNetwork: (ssid: String, bssid: String)?
    if let interfaces = CNCopySupportedInterfaces() as NSArray? {
        for interface in interfaces {
            let name = interface as! CFString
            if let interfaceData = CNCopyCurrentNetworkInfo(name) as NSDictionary? {
                if let ssid = interfaceData[kCNNetworkInfoKeySSID] as? String,
                    let bssid = interfaceData[kCNNetworkInfoKeyBSSID] as? String {
                    wifiNetwork = (ssid: ssid, bssid: bssid)
                }
            }
        }
    }
    
    return wifiNetwork
}

权限 - CoreLocation

就用户权限而言,您有可能,但您需要在CNCopyCurrentNetworkInfofetchCurrent文档中定义的四个之一- 在大多数情况下,我假设您需要添加 CoreLocation 并请求使用用户位置的权限。例如,Privacy - Location When In Use Usage Description在 Info.plist 中需要说明您需要用户位置的原因,然后您必须拨打电话以请求用户授权对话框。

    import CoreLocation

    CLLocationManager().requestWhenInUseAuthorization()

权利

您的应用程序还需要授权 -在项目的Signing and Capabilities部分中com.apple.developer.networking.wifi-info添加,称为Access WiFi Information。使用方法时,需要额外的网络扩展权利。NEHotspotNetwork

于 2020-12-04T08:44:07.507 回答
0

以下函数返回wifi名称和Mac地址

    func getNetworkInfo()->(success:Bool,ssid:String,mac:String){
      var currentSSID:String = ""
      var macAdrees:String = ""
      var succes:Bool = false
      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
            macAdrees = interfaceData["BSSID"] as! String
            succes = true
        } else {
            currentSSID = ""
        }
    }

    return (succes, currentSSID, macAdrees)
}

这段代码工作正常。你会在你的开发目标中注意到一些警告 >= iOS9

于 2016-03-23T16:21:17.337 回答
0

您可以使用更新的 Swift 标准 @japes 答案找到另一个答案,该标准同时支持Swift 3Swift 4""在模拟器上返回空。

import SystemConfiguration.CaptiveNetwork

internal class SSID {

    class func fetchSSIDInfo() -> String {
        var currentSSID = ""
        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 currentSSID
                }
                guard let interfaceData = unsafeInterfaceData as? [String: Any] else {
                    return currentSSID
                }
                guard let SSID = interfaceData["SSID"] as? String else {
                    return currentSSID
                }
                currentSSID = SSID
            }
        }
        return currentSSID
    }

}
于 2018-03-16T14:23:20.137 回答
0

https://stackoverflow.com/users/3108877/rob的答案——更短的版本

func getSSID() -> String? {
        if let interface = (CNCopySupportedInterfaces() as? [String])?.first,
            let unsafeInterfaceData = CNCopyCurrentNetworkInfo(interface as CFString) as? [String: Any],
            let ssid = unsafeInterfaceData["SSID"] as? String {
            return ssid
        }
        return nil
    }
于 2017-07-18T06:05:43.577 回答