I\'m trying to write a program that will scan for available serial ports and present them in a popup menu. Why can I not take the CFString
straight from the
At least as of Swift 2.0 (verify from a terminal with swift --version
), you can convert a CFString
to a native Swift String
with a simple as String
.
This is sufficient, since Swift's String
type can be used anywhere NSString
is expected.
An example with a kUTType*
constant (kUTType*
constants are defined by CoreServices and are CFString
s):
// Get UTF8 plain text from the pasteboard.
import AppKit
let str = NSPasteboard.generalPasteboard().stringForType(kUTTypeUTF8PlainText as String)
A more detailed example:
// 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
To test what type you're dealing with:
cfStr is CFString // true
swiftStr is String // true
To get the string's type, use .dynamicType
; in a string context, this reports the type name but note that you may get the name of a private internal class back:
"cfStr is a \(cfStr.dynamicType) instance."
// -> "cfStr is a _NSContiguousString instance." !!
Still, you can treat this as a CFString
, as the is
test above shows.
Use _stdlib_getDemangledTypeName()
to get the true, underlying class name:
_stdlib_getDemangledTypeName(cfStr) // -> "ObjectC.CFString"
_stdlib_getDemangledTypeName(kUTTypeUTF8PlainText) // ditto
Swift.String and NSString are toll free bridged.
NSString and CFString can be cast to one another, but you can't directly cast from a Swift String to a CFString or vice versa.
Follow these steps to cast from a Core Foundation String to a Swift String:
var cfStr:CFString = "Soon, I'll be a Swift String"
var nsTypeString = cfStr as NSString
var swiftString:String = nsTypeString
Example for CFTypeRef:
var cfStr:CFTypeRef = "Soon, I'll be a Swift String"
var nsTypeString = cfStr as NSString
var swiftString:String = nsTypeString
As for me, I like to make extentions and use them afterwards. It seems convenient and clear to read:
Extention:
extension CFString {
var string: String {
return self as String
}
}
Usage:
let specificQueryPart: [String: NSObject] = [
kSecReturnData.string: true as NSObject,
kSecAttrService.string: key as NSObject,
kSecMatchLimit.string: kSecMatchLimitOne
]