UTF16 存储的字符串在从 CoreData 检索回来后不匹配

UTF16 stored string doesn't match once retrieved back from CoreData

所以我使用 CoreStore 在 CoreData 中保存一个字符串 identifier。 该字符串可能包含一些瑞典语 UTF16 字符。从调试器控制台检查:

> po identifier
"/EXTERNAL/Gemensam RUN/FileCloud Test/Test folder åäö/Test with Swedish characters - åäö.xlsx"

保存回 CoreData 后立即:

>po record
<File: 0x281e140a0> (entity: File; id: 0xdcac6620f1e9eb63 <x-coredata://BA0168AF-92CE-4AC2-A934-1020E41C5C20/File/p615>; data: {
    // ...
    identifier = "filecloud.test@run.se@files.runcloud.se/EXTERNAL/Gemensam RUN/FileCloud Test/Test folder \U00e5\U00e4\U00f6/Test with Swedish characters - \U00e5\U00e4\U00f6.xlsx";
    // ...
})

看起来 UTF16 字符串已存储为 UTF8 字符串。但仍然是有效的:

> po record.identifier == identifier
true

稍后尝试使用 UTF16 瑞典语 identifier 字符串检索 record 时出现问题,因为它不再匹配了。

CoreStore.fetchOne(From<Record>().where(\.identifier == identifier)) // Fails

如何将 identifier 转换为与存储的 CoreData 值匹配的表示形式?

更新

更奇怪的是,硬编码标识符确实成功了:

CoreStore.fetchOne(From<Record>().where(\.identifier == "filecloud.test@run.se@files.runcloud.se/EXTERNAL/Gemensam RUN/FileCloud Test/Test folder åäö/Test with Swedish characters - åäö.xlsx")) // Works

并且 identifer 和这个硬编码字符串匹配:

po identifier == "filecloud.test@run.se@files.runcloud.se/EXTERNAL/Gemensam RUN/FileCloud Test/Test folder åäö/Test with Swedish characters - åäö.xlsx"
true

但是使用 identifier 而不是硬编码的则不会。

更新 2

比较 identifier.unicodeScalars 和硬编码字符串确实表明它们确实不同:

CoreData确实保存和return字符串完全一样。

尝试使用复杂字符检索值的问题是 CoreData(很可能是它背后的 SQLite)不认为我的句子相等,因为它们有不同 grapheme clusters。两个句子都是有效的,并且在 Swift 中比较相等,但在 CoreData 中不相等作为检索对象的值。

在 Swift 中似乎没有合适的方法来转换字素簇,所以我的解决方法是重新创建最初导致原始字素簇的过程。这涉及首先从字符串中创建一个 URL,然后让 FileProvider 框架通过调用 persistentIdentifierForItem(at: url)!.rawValue 创建相同的字素簇。然后使用这个值来检索我保存的对象。