所以我正在使用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 = "[email protected]@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瑞典语record
字符串来检索identifier
时,因为它不再匹配。
CoreStore.fetchOne(From<Record>().where(\.identifier == identifier)) // Fails
如何将identifier
转换为与存储的CoreData值匹配的表示形式?
更新
更奇怪的是,硬编码标识符确实成功:
CoreStore.fetchOne(From<Record>().where(\.identifier == "[email protected]@files.runcloud.se/EXTERNAL/Gemensam RUN/FileCloud Test/Test folder åäö/Test with Swedish characters - åäö.xlsx")) // Works
[identifer
和此硬编码的字符串确实匹配:
po identifier == "[email protected]@files.runcloud.se/EXTERNAL/Gemensam RUN/FileCloud Test/Test folder åäö/Test with Swedish characters - åäö.xlsx"
true
但是不使用identifier
而不是硬编码的代码。
更新2
比较.unicodeScalars
的identifier
和硬编码的字符串确实表明它们确实有所不同:
CoreData确实保存和返回了完全相同的字符串。
尝试使用复杂字符检索值的问题是CoreData(并且很可能是其背后的SQLite)不认为我的句子相等,因为它们具有不同的grapheme clusters。这两个句子都是有效的,并且在Swift中比较相等,但在CoreData中不是相等的值作为检索对象。
似乎没有在Swift中转换字形簇的正确方法,因此我的解决方法是重新创建导致最初具有原始字形簇的过程。这涉及首先从字符串中创建一个URL
,然后通过调用FileProvider
让persistentIdentifierForItem(at: url)!.rawValue
框架创建相同的字素簇。然后使用此值检索我保存的对象。