string swift serial-port iokit

Convertir CFString a NSString-Swift



serial-port iokit (2)

Estoy intentando escribir un programa que buscará los puertos serie disponibles y los presentará en un menú emergente. ¿Por qué no puedo tomar el CFString directamente de la función IORegistryEntryCreateCFProperty() y agregarlo al menú mediante la interpolación de cadenas en la siguiente línea? Por alguna razón mi declaración de variable se cumple con el error:

"NSString no es un subtipo de CFString".

import Foundation import Cocoa import IOKit import IOKit.serial @objc class Serial { init() { } @IBOutlet var serialListPullDown : NSPopUpButton! func refreshSerialList(defaultprompt: String) { let masterPort: mach_port_t = kIOMasterPortDefault let classesToMatch: CFDictionary = IOServiceMatching(kIOSerialBSDServiceValue).takeUnretainedValue() var matchingServices: io_iterator_t = 0 // remove everything from the pull down list serialListPullDown?.removeAllItems() // ask for all the serial ports let kernResult = IOServiceGetMatchingServices(masterPort, classesToMatch, &matchingServices) if kernResult == KERN_SUCCESS { // success while (io_object_t() == IOIteratorNext(matchingServices)) { var serialport = IORegistryEntryCreateCFProperty(io_object_t(), kIOCalloutDeviceKey, kCFAllocatorDefault, 0) serialListPullDown?.addItemWithTitle("/(serialport)") } } else { // error } } }


Swift.String y NSString están puenteados sin cargo.

NSString y CFString se pueden convertir entre sí, pero no se puede convertir directamente de una Cadena Swift a una CFString o viceversa.

Siga estos pasos para emitir desde una Cadena Core Foundation a una Cadena Swift:

var cfStr:CFString = "Soon, I''ll be a Swift String" var nsTypeString = cfStr as NSString var swiftString:String = nsTypeString

Ejemplo para CFTypeRef:

var cfStr:CFTypeRef = "Soon, I''ll be a Swift String" var nsTypeString = cfStr as NSString var swiftString:String = nsTypeString


Al menos a partir de Swift 2.0 (verifique desde una terminal con swift --version ), puede convertir un CFString a un Swift String nativo con un simple as String .

Esto es suficiente, ya que el tipo String de Swift se puede usar en cualquier lugar NSString se espere NSString .

Un ejemplo con una constante kUTType* (las constantes kUTType* están definidas por CoreServices y son CFString s):

// Get UTF8 plain text from the pasteboard. import AppKit let str = NSPasteboard.generalPasteboard().stringForType(kUTTypeUTF8PlainText as String)

Un ejemplo más detallado :

// Import at least the Foundation framework. // Since Cocoa includes Foundation, `import Cocoa` works too. // (Note that `import CoreServices`, even though it defines type `CFString`, // is NOT enough - the conversion will fail.) import Foundation // Create a CFString. // The fact that initializing from a `String` literal here works implies that // the *reverse* cast - String -> CFString - also works. var cfStr:CFString = "Cast me." // Convert it to String. var swiftStr = cfStr as String

Para probar con qué tipo estás tratando:

cfStr is CFString // true swiftStr is String // true

Para obtener el tipo de cadena , use .dynamicType ; en un contexto de cadena, esto informa el nombre del tipo, pero tenga en cuenta que puede recuperar el nombre de una clase interna privada :

"cfStr is a /(cfStr.dynamicType) instance." // -> "cfStr is a _NSContiguousString instance." !!

Aún así, puedes tratar esto como una CFString , como lo demuestra la prueba anterior.

Use _stdlib_getDemangledTypeName() para obtener el verdadero nombre de clase subyacente :

_stdlib_getDemangledTypeName(cfStr) // -> "ObjectC.CFString" _stdlib_getDemangledTypeName(kUTTypeUTF8PlainText) // ditto