Использование NSPersistentDocument для создания «Документов»

Я хотел бы создать приложение, которое использует

  • Быстрый
  • CoreData
  • «Документы», которые работают в стандартной манере macOS [настраиваемое расширение, один «файл»/файловая обертка, содержащий все данные, относящиеся к этому документу]

Это не представляется возможным. В документации очень четко указано, что

NSPersistentDocument не поддерживает некоторые варианты поведения документов: Обертки файлов. [..]

что заставляет меня думать, что обычные способы работы с изображениями в CoreData — бинарные данные с «разрешить внешнее хранилище» и сохранение их в другом месте, сохранение URL-адреса в базе данных - нельзя использовать с NSPersistentDocument. Я хочу, чтобы мои пользователи могли выполнять обычные операции Finder с моим «файлом» (дублировать, перемещать во внешнее хранилище, восстанавливать из внешней резервной копии), и мне нужно, чтобы все мои данные были в одном пакете.

SQL-версия хранилища файлов приводит к обычному тройному стеку при сохранении - .sqlite, .sqlite-shm, .sqlite-wal - который бесполезен в качестве «документа».

Есть ли решение, которое я упустил из виду? (примеры очень скудны; пример Big Nerd Ranch не решает это тоже; ни Маркус Зарра, ни Objc.io не касаются NSPersistentDocument).


person green_knight    schedule 27.07.2017    source источник


Ответы (2)


Единственный вариант, который будет работать с NSPersistentDocument так, как вы хотите, — это хранить изображения непосредственно в базе данных. Вам нужен атрибут двоичных данных для вашей сущности, но вы не можете включить параметр Allows External Storage.

Если вы включите эту опцию, Core Data решит — в зависимости от размера — хранить ли изображение непосредственно в базе данных или в скрытой папке внутри папки, где находится ваш документ:

Скрытая папка

(Я сделал папку видимой, введя cmd-shift-. в Finder). Образец документа называется Test 1.doof и содержит три изображения:

Окно документа

Вы можете видеть, что скрытая папка .Test 1_SUPPORT/EXTERNAL DATA содержит два файла, которые представляют собой два больших изображения (1,3 МБ и 494 КБ). Третий файл размером всего 50 КБ хранится внутри Test 1.doof. Если вы переместите Test 1.doof в другую папку, скрытая папка останется. Открытие файла в этой другой папке приводит к отсутствию двух изображений.

Хранение изображений внутри базы данных не так уж плохо, если вы поместите двоичные данные в отдельный объект с отношением один к одному к остальным данным, например так:

Модель данных

Таким образом, изображение не мешает операциям поиска или сортировки. NSPersistentDocument дает вам много интересных функций бесплатно, поэтому вы должны использовать их в любом случае, если это возможно.

Два дополнительных замечания:

  • Если вы включаете Allows External Storage для атрибута, вам не нужно заботиться об URL-адресах или о том, где хранить изображения, Core Data сделает это за вас (но бесполезно для приложений на основе документов).
  • Эти файлы shm или wal являются временными файлами, которые появляются «иногда» и для баз данных без внешнего хранилища. Если они прилипают, вы можете безопасно удалить их, когда приложение закрыто.
person Dirk    schedule 09.09.2017

Если вы хотите поместить в документ больше, чем просто базу данных, вам следует реализовать NSDocument вместо NSPersistentDocument. В этом случае вы не получаете встроенной поддержки CoreData, но можете использовать свой документ в качестве контейнера для нескольких типов файлов.

См. также Возможна ли комбинация NSDocument и CoreData, или NSPersistentDocument единственный способ?

person Ely    schedule 11.08.2017
comment
Как создать отдельные хранилища CoreData (sql) внутри файловой оболочки? Связанный пример предлагает одно хранилище CoreData для всей информации, с отдельными документами, использующими другой тип хранилища (plist и т. д.), тогда как я действительно ищу «документ», который использует CoreData. - person green_knight; 14.08.2017
comment
Вы также можете создать экземпляр стека Core Data в рамках NSDocument и сохранить ваши файлы SQLite, XML или двоичные файлы в документе. - person Ely; 14.08.2017