I’d expect this code to return an NSString
with the ID of the currently selected input source. Instead, it seems to return one of the NSString
classes itself.
import Foundation
import Carbon
let current = TISCopyCurrentKeyboardInputSource().takeUnretainedValue()
let id = TISGetInputSourceProperty(current, kTISPropertyInputSourceID).load(as: NSString.self)
id.length
When I run this in my macOS app, I get this error message in the logs: +[__NSCFConstantString _fastCStringContents:]: unrecognized selector sent to class 0x7fff92cf79e8
. How can I fix this issue so I get the correct returned value?
TISGetInputSourceProperty()
returns an (unmanaged) raw pointer which must be converted to a CFStringRef
, not dereferenced with load()
. The CFString
can then be bridged to a Swift String
.
let current = TISCopyCurrentKeyboardInputSource().takeRetainedValue()
if let ptr = TISGetInputSourceProperty(current, kTISPropertyInputSourceID) {
let id = Unmanaged<CFString>.fromOpaque(ptr).takeUnretainedValue() as String
print(id) // com.apple.keylayout.German
}
Note also that takeRetainedValue()
must be used on the return value of TISCopyCurrentKeyboardInputSource()
because that function returns a (+1) retained reference, otherwise you'll have a memory leak.