利用可能なシリアルポートをスキャンしてポップアップメニューに表示するプログラムを作成しようとしています。 CFString
をIORegistryEntryCreateCFProperty()
関数から直接取得して、次の行の文字列補間を介してメニューに追加できないのはなぜですか?何らかの理由で、変数の宣言がエラーに遭遇しました:
「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
}
}
}
Swift.StringとNSStringはフリーブリッジです。
NSStringとCFStringは互いにキャストできますが、Swift StringからCFStringに、またはその逆に直接キャストすることはできません。
次の手順に従って、コアファンデーション文字列からSwift文字列にキャストします。
var cfStr:CFString = "Soon, I'll be a Swift String"
var nsTypeString = cfStr as NSString
var swiftString:String = nsTypeString
CFTypeRefの例:
var cfStr:CFTypeRef = "Soon, I'll be a Swift String"
var nsTypeString = cfStr as NSString
var swiftString:String = nsTypeString
少なくともSwift 2.(_Swift --version
_を使用して端末から確認)、次のことができますCFString
をネイティブのSwift String
with a simple _as String
_。
SwiftのString
型はNSString
が必要な場所であればどこでも使用できるため、これで十分です。
_kUTType*
_定数を含むexample(_kUTType*
_定数はCoreServicesによって定義され、CFString
s):
_// Get UTF8 plain text from the pasteboard.
import AppKit
let str = NSPasteboard.generalPasteboard().stringForType(kUTTypeUTF8PlainText as String)
_
A より詳細な例:
_// 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
_
どのタイプをテストするあなたが扱っている:
_cfStr is CFString // true
swiftStr is String // true
_
文字列のタイプを取得するには、_.dynamicType
_を使用します。文字列のコンテキストでは、これはtype nameを報告しますが、private internalクラスの名前が返される可能性があることに注意してください:
_"cfStr is a \(cfStr.dynamicType) instance."
// -> "cfStr is a _NSContiguousString instance." !!
_
それでも、上記のCFString
テストが示すように、これをis
として扱うことができます。
_stdlib_getDemangledTypeName()
を使用して取得true、基になるクラス名:
__stdlib_getDemangledTypeName(cfStr) // -> "ObjectC.CFString"
_stdlib_getDemangledTypeName(kUTTypeUTF8PlainText) // ditto
_