String Swift:CFArray:获取UTF字符串形式的值

String Swift:CFArray:获取UTF字符串形式的值,string,swift,utf-8,String,Swift,Utf 8,我调用了一些返回CFStringRef值的CFArray的函数。我需要从他们那里得到utf字符串。由于我不想让我的代码太复杂,我做了以下工作: let initString=“\(TISCreateInputSourceList(nil,false).takeUnrepainedValue())” 然后我将结果字符串按\ns拆分,得到一个Swift字符串数组。但是,当函数开始返回非ascii字符串时,问题就出现了。我开始得到像“\U2345\U2344”这样的字符串 然后我尝试获取CFArray

我调用了一些返回
CFStringRef
值的
CFArray
的函数。我需要从他们那里得到utf字符串。由于我不想让我的代码太复杂,我做了以下工作:

let initString=“\(TISCreateInputSourceList(nil,false).takeUnrepainedValue())”

然后我将结果字符串按
\n
s拆分,得到一个Swift字符串数组。但是,当函数开始返回非ascii字符串时,问题就出现了。我开始得到像“\U2345\U2344”这样的字符串

然后我尝试获取CFArray并对其进行迭代,以获取值,并可能将它们转换为字符串,但我无法从中获取值:

let ar=TISCreateInputSourceList(nil,true).takeUnrepainedValue()
对于0中的i…CFArrayGetCount(ar)-1{
打印(“>>(CFArrayGetValueAtIndex(ar,i.memory)”)
}

值始终为空


如何获得实际值?

这里有一些问题。首先,
TISCreateInputSourceList()
在其名称中有“Create”,这意味着它返回一个(+1)个保留值 对象,您必须使用
takeRetainedValue()
获取值, 不要
获取未恢复的值()
,否则代码将泄漏内存:

let srcs = TISCreateInputSourceList(nil, true).takeRetainedValue()
现在可以使用
CFArray…
方法从数组中获取值, 但将其转换为
NSArray
(即“免费桥接”)要容易得多:

这不是一个
CFStringRef
值数组,而是一个
tiInputSource
对象。您可以将
NSArray
转换为Swift数组:

let srcs = TISCreateInputSourceList(nil, true).takeRetainedValue()
                    as NSArray as! [TISInputSource]
强制施放
as在这里是可以接受的,因为函数是
记录以返回输入源数组

现在,您可以简单地迭代数组的元素:

for src in srcs  {
    // do something with `src` (which is a `TISInputSource`)
}
使用
TISGetInputSourceProperty()
函数检索输入源的属性,例如:

let ptr = TISGetInputSourceProperty(src, kTISPropertyInputSourceID)
这将返回一个“空指针”(
UnsafeMutablePointer
),必须将其转换为对象 适当类型的指针(对于
kTISPropertyInputSourceID
property)。不幸的是,这有点 复杂(比较):

总而言之:

let srcs = TISCreateInputSourceList(nil, true).takeRetainedValue()
                as NSArray as! [TISInputSource]
for src in srcs  {
    let ptr = TISGetInputSourceProperty(src, kTISPropertyInputSourceID)
    let val = Unmanaged<CFString>.fromOpaque(COpaquePointer(ptr)).takeUnretainedValue()
                as String
    print(val)
}
let srcs=TISCreateInputSourceList(nil,true)
和…一样可怕![输入源]
对于src中的src{
设ptr=TISGetInputSourceProperty(src,kTISPropertyInputSourceID)
让val=Unmanaged.from不透明(COpaquePointer(ptr)).takeUnrepainedValue()
作为字符串
打印(val)
}

@Noobie:No.
让srcs=TISCreate….takeRetainedValue()
转移所有权,当
srcs
超出范围时,数组将被释放(因为Swift使用ARC)
let ptr = TISGetInputSourceProperty(src, kTISPropertyInputSourceID)
let val = Unmanaged<CFString>.fromOpaque(COpaquePointer(ptr)).takeUnretainedValue()
let val = Unmanaged<CFString>.fromOpaque(COpaquePointer(ptr)).takeUnretainedValue()
                    as String
let srcs = TISCreateInputSourceList(nil, true).takeRetainedValue()
                as NSArray as! [TISInputSource]
for src in srcs  {
    let ptr = TISGetInputSourceProperty(src, kTISPropertyInputSourceID)
    let val = Unmanaged<CFString>.fromOpaque(COpaquePointer(ptr)).takeUnretainedValue()
                as String
    print(val)
}