web-dev-qa-db-ja.com

CFStringをNSStringに変換-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
        }

    }
}
19
user3185748

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
15
Woodstock

少なくともSwift 2.(_Swift --version_を使用して端末から確認)、次のことができますCFStringをネイティブのSwift String with a simple _as String_

SwiftのString型はNSStringが必要な場所であればどこでも使用できるため、これで十分です。

_kUTType*_定数を含むexample(_kUTType*_定数はCoreServicesによって定義され、CFStrings):

_// 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
_
13
mklement0