Get SSID in Swift 2

2019-01-17 08:24发布

问题:

Im trying to use this code to get 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
    }
}

But in getting an error in this line let interfacesArray = interfaces.takeRetainedValue() as [String : AnyObject]

The error is

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

Thanks for your help

回答1:

This may help you (tested on 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
    }
}

I took and adapted the code from Ray Wenderlich's site (once was here: Retrieve SSID in iOS9 but now the specific thread has been removed from site)

iOS 12

You must enable Access WiFi Information from capabilities.

Important To use this function in iOS 12 and later, enable the Access WiFi Information capability for your app in Xcode. When you enable this capability, Xcode automatically adds the Access WiFi Information entitlement to your entitlements file and App ID. Documentation link

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"] as! String
                    debugPrint("ssid=\(currentSSID), BSSID=\(BSSID), SSIDDATA=\(SSIDDATA)")
                }
            }
        }
        return currentSSID
    }
}


回答2:

This is my solution Swift 3 iOS 10 and it works well with 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
    }

}

To use it:

let wifiName = network().getSSID()

    guard wifiName != nil else {

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

        return
    }


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

PS: Attention it not works on simulator



回答3:

All the presented at the moment solutions seems rather complex, with ugly unsafe casts.

I was able to craft such a concise solution (with no black magic at all):

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
}


回答4:

In Swift 3 (works in real device and simulator):

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

Usage:

SSID.fetchSSIDInfo()

//will return "" if no connected wifi or running in simulator 


回答5:

In swift 2, you don't have to call takeRetainedValue.

Replace the code interfaces.takeRetainedValue() as [String : AnyObject] with Array(arrayLiteral: interfaces).

Also remember change the code interfacesArray[0] as String into String(interfacesArray[0]).

Full code :

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
}

}



回答6:

Swift 4 version

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
}


回答7:

The following function return the wifi name and the Mac address

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

This code works fine. You will note some warning in your development target >= iOS9



回答8:

https://stackoverflow.com/users/3108877/rob's answer -- shorter version

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
    }


回答9:

You can find an another answer with updated Swift standards of @japes answer which supports both Swift 3 and Swift 4. Return empty "" on simulators.

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
    }

}