Сохраненная строка в формате UTF16 не совпадает после извлечения из CoreData - PullRequest
0 голосов
/ 01 ноября 2019

Поэтому я использую CoreStore , чтобы сохранить строку identifier в CoreData. Строка может иметь некоторые шведские символы 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

Проблема возникает позже, когда вы пытаетесь получить record снова с шведской identifier строкой UTF16, как оригинал выше, поскольку она больше не соответствует.

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

Сравнение .unicodeScalars из identifier и жестко закодированной строки действительно показывает, что они действительно различаются:

enter image description here

1 Ответ

0 голосов
/ 05 ноября 2019

CoreData сохраняет и возвращает строки точно так же.

Проблема при попытке извлечь значения с использованием сложных символов заключается в том, что CoreData (и, скорее всего, SQLite за ним) не считают мои предложения равными, поскольку они имеют разные графемных кластера . Оба предложения действительны и сравниваются в Swift, но не в CoreData, а в качестве значений для извлечения объектов.

Кажется, что не существует подходящего способа преобразования кластеров графем в Swift, поэтому мой обходной путь заключался в воссоздании процессаэто приводит к тому, что исходные кластеры графем в первую очередь. Для этого сначала нужно создать URL из строки, а затем позволить инфраструктуре FileProvider создать те же кластеры графем, вызвав persistentIdentifierForItem(at: url)!.rawValue. Затем используйте это значение для извлечения моего сохраненного объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...