将CFString转换为NSString - Swift

use*_*748 18 string serial-port iokit swift

我正在尝试编写一个程序来扫描可用的串行端口并在弹出菜单中显示它们.为什么我不能CFStringIORegistryEntryCreateCFProperty()函数中取直接并在下一行通过字符串插值将其添加到菜单中?由于某种原因,我的变量声明遇到错误:

"NSString不是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
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

Woo*_*ock 15

Swift.String和NSString是免费桥接的.

NSString和CFString可以相互转换,但是不能直接从Swift String转换为CFString,反之亦然.

按照以下步骤从Core Foundation String转换为Swift String:    

var cfStr:CFString = "Soon, I'll be a Swift String"
var nsTypeString = cfStr as NSString
var swiftString:String = nsTypeString
Run Code Online (Sandbox Code Playgroud)

CFTypeRef的示例:

var cfStr:CFTypeRef = "Soon, I'll be a Swift String"
var nsTypeString = cfStr as NSString
var swiftString:String = nsTypeString
Run Code Online (Sandbox Code Playgroud)


mkl*_*nt0 13

至少从Swift 2.0开始(从终端验证swift --version),你可以用简单的方法将a转换CFString为原生的SwiftStringas String.

这已经足够了,因为Swift的String类型可以在任何NSString预期的地方使用.

一个带常量的例子kUTType*(kUTType*常量由CoreServices定义,是CFStrings):

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

一个更详细的例子:

// 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
Run Code Online (Sandbox Code Playgroud)

测试您正在处理的类型:

cfStr is CFString // true
swiftStr is String // true
Run Code Online (Sandbox Code Playgroud)

获取字符串的类型,请使用.dynamicType; 在字符串上下文中,这会报告类型名称,但请注意您可能会获得私有内部类的名称 :

"cfStr is a \(cfStr.dynamicType) instance."
// -> "cfStr is a _NSContiguousString instance." !!
Run Code Online (Sandbox Code Playgroud)

不过,CFString正如is上面的测试所示,您可以将其视为一个.

使用_stdlib_getDemangledTypeName()得到真正的,潜在的类名:

_stdlib_getDemangledTypeName(cfStr) // -> "ObjectC.CFString"
_stdlib_getDemangledTypeName(kUTTypeUTF8PlainText) // ditto
Run Code Online (Sandbox Code Playgroud)