Pregunta Swift CNCopySupportedInterfaces no válido


Intentando obtener el SSID del dispositivo actual. He encontrado muchos ejemplos sobre cómo hacerlo, pero estoy luchando para que CNCPySupportedInterfaces se autocomplete. Tengo 'import SystemConfiguration' en la parte superior de mi archivo rápido, pero sin éxito. Parece que no puedo entender lo que estoy haciendo mal.


10
2017-07-31 21:47


origen


Respuestas:


Necesitas import SystemConfiguration.CaptiveNetwork

Debajo de las portadas, CaptiveNetwork es un archivo de encabezado C (.h) que está dentro del marco de configuración del sistema:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/SystemConfiguration.framework/Headers/CaptiveNetwork.h

Si conoces Objective-C, esto entra en más profundidad:

iPhone recibe SSID sin biblioteca privada

Además, el autocompletado no está satisfecho con los elementos globales heredados; solo quiere clases en el nivel superior. Probablemente porque hay demasiados @ # $ @ # globales.

Ah, y tienes que escribir este maravilloso fragmento para que funcione:

    for interface in CNCopySupportedInterfaces().takeRetainedValue() as! [String] {
        println("Looking up SSID info for \(interface)") // en0
        let SSIDDict = CNCopyCurrentNetworkInfo(interface).takeRetainedValue() as! [String : AnyObject]
        for d in SSIDDict.keys {
            println("\(d): \(SSIDDict[d]!)")
        }
    }

ADDENDUM PARA SWIFT 2.2 y 3.0

El puenteo se ha simplificado pero se ha vuelto a complicar para CFxxx tipos de datos y ahora desenvolver y se requiere mucho transbordo, pero no llamadas retenidas. No sé si Swift 2 ha facilitado las cosas, pero está bastante claro lo que está sucediendo, además del nil nos ayuda a identificar el simulador. La otra respuesta usa muchísimas operaciones inseguras y de lanzamiento de bits que parecen no pertenecer a Swiftian, así que ofrezco esto.

    func getInterfaces() -> Bool {
        guard let unwrappedCFArrayInterfaces = CNCopySupportedInterfaces() else {
            print("this must be a simulator, no interfaces found")
            return false
        }
        guard let swiftInterfaces = (unwrappedCFArrayInterfaces as NSArray) as? [String] else {
            print("System error: did not come back as array of Strings")
            return false
        }
        for interface in swiftInterfaces {
            print("Looking up SSID info for \(interface)") // en0
            guard let unwrappedCFDictionaryForInterface = CNCopyCurrentNetworkInfo(interface) else {
                print("System error: \(interface) has no information")
                return false
            }
            guard let SSIDDict = (unwrappedCFDictionaryForInterface as NSDictionary) as? [String: AnyObject] else {
                print("System error: interface information is not a string-keyed dictionary")
                return false
            }
            for d in SSIDDict.keys {
                print("\(d): \(SSIDDict[d]!)")
            }
        }
        return true
    }

[También, después de 10 minutos, el autocompletado comenzó a funcionar para CNxxx. Claramente, un hilo de fondo está ocupadamente digiriendo miles de globales en SourceKit.]

Salida en el éxito:

SSIDDATA: <57696c6d 79>

BSSID: 12: 34: 56: 78: 9a: a.

SSID: YourSIDIDHere


19
2017-07-31 22:37



En Swift 2.0 / iOS 9, API CaptiveNetwork está (casi) desaparecida o depreciada. Contacté a Apple con respecto a este problema y pensé que podríamos (o deberíamos) usar NEHotspotHelper en su lugar. Recibí una respuesta de Apple hoy: uno debe continuar utilizando CaptiveNetwork y las dos API relevantes (incluso difíciles de marcar como depreciadas):

 CNCopySupportedInterfaces
 CNCopyCurrentNetworkInfo

El usuario braime publicó un fragmento de código actualizado para este problema en Foros de Ray Wenderlich:

 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
        } else {
            currentSSID = ""
        }
    }

Funciona perfecto para mi


9
2017-09-28 23:44



Rápido:

import SystemConfiguration.CaptiveNetwork

func currentSSIDs() -> [String] {
        guard let interfaceNames = CNCopySupportedInterfaces() as? [String] else {
            return []
        }
        return interfaceNames.flatMap { name in
            guard let info = CNCopyCurrentNetworkInfo(name as CFString) as? [String:AnyObject] else {
                return nil
            }
            guard let ssid = info[kCNNetworkInfoKeySSID as String] as? String else {
                return nil
            }
            return ssid
        }
    }

Entonces print(currentSSIDs()), no funciona en simulador, solo dispositivos reales.

Tomado de https://forums.developer.apple.com/thread/50302


0
2017-12-06 20:14