Должен ли я использовать NSFileWrappers в UIManagedDocument?

Я пытаюсь сохранить список и несколько двоичных файлов (скажем, изображений) как часть UIManagedDocument. Имя двоичных файлов является атрибутом в Core Data, и мне не нужно их перечислять, просто перейдите к нужному файлу при отображении связанной сущности.

Я хочу иметь следующую файловую структуру:

 - <File yyyyMMdd-HHmmss>.extdoc
   - StoreContent
     - persistentStore
   - AdditionalContent
     - ListStatus.plist (used to store per document defaults)
       - Images
         - uuid1.png
         - uuid2.png
         - ...
         - uuidn.png

Пока что я успешно выполнил инструкции в Как мне сохранить дополнительный контент в пакеты файлов UIManagedDocument?, но когда я пытаюсь добавить двоичные файлы, есть некоторые вещи, которые я не знаю, как сделать.

  1. Следует ли рассматривать URL / путь / файл yyyyMMdd-HHmmss.extdoc / AdditionalContent (тот, который по умолчанию предоставляется с readAdditionalContentFromURL: error :) как NSFileWrapper? Есть ли какие-либо преимущества / недостатки по сравнению с использованием только URL-адресов? Я считаю более сложным использовать файловую оболочку, так как plist должен быть прочитан с использованием средств доступа к файловой оболочке и NSCoder (я думаю), а файлы, я должен сохранить файловую оболочку для каталога изображений, а затем получить соответствующий узел с objectForKey (я полагаю). Но в Руководстве по программированию приложений на основе документов Apple для iOS, касающемся пользовательских форматов вместо NSData или NSFileWrapper, говорится: «Имейте в виду, что ваш код должен будет дублировать то, что UIDocument делает для вас, и поэтому вам придется иметь дело с большей сложностью и большая вероятность ошибки. «Я неправильно понимаю это?
  2. Значения по умолчанию для каждого документа объявляются как свойства: установщик изменяет NSDictionary, который отображает список и помечает документ как обновленный, а средство получения обращается к словарю с правильным ключом. Как мне предоставить возможность чтения / записи двоичных файлов? Следует ли мне добавить метод в свой подкласс UIManagedDocument? - (void) writeImage: (NSString *) uuid; и - (UIImage *) readImage: (NSString *) uuid; И следует ли мне хранить эти данные в памяти, пока документ не будет сохранен? Как?
  3. Предполагая, что NSFileWrapper - это то, что вам нужно, если я планирую использовать этот документ с iCloud, следует ли мне использовать файловые координаторы с файловой оболочкой? Если да, то как?

Мы будем очень признательны за любой исходный код для каждого вопроса. Спасибо.

P.S .: Я знаю, что могу сохранить некоторые двоичные данные внутри Core Data, но мне не нравится это решение. Среди других причин я предпочитаю хранить данные PNG для файлов изображений, сериализованную версию UIImage, которая не будет совместима с NSImage, если я хочу создать настольное приложение.


person Jorge Ortiz    schedule 29.02.2012    source источник


Ответы (3)


Хочу сказать, что в целом UIManagedDocument мне больше нравится. У него есть несколько преимуществ перед необработанными Core Data. Например, он автоматически настраивает весь основной стек данных. Он также настраивает для вас контексты вложенных управляемых объектов, так что вы получаете бесплатное фоновое сохранение. Ничто из этого не особо впечатляет, но это большая функциональность с крошечным объемом кода.

Я не играл с сохранением дополнительной информации ... но вот мои мысли.

Во-первых, вам не нужно рассматривать новый URL как файловую оболочку. Вы должны просто иметь возможность выполнять обычные файловые операции с предоставленным URL-адресом. Просто убедитесь, что у вас все реализовано правильно в additionalContentForURL: error :, writeAdditionalContent: toURL: originalContentsURL: error: и readAdditionalContentFromURL: error :. Операции чтения и записи должны быть симметричными. И вам, вероятно, следует сделать снимок ваших данных в additionalContentsForURL: error: так, чтобы все было сохранено в известном, хорошем состоянии (поскольку операции сохранения являются асинхронными).

В качестве альтернативы, рассматривали ли вы использование флага «Сохранить во внешнем файле записи» в своей модели данных вместо того, чтобы сохранять его вручную? Это должно заставить Core Data (в зависимости от размера двоичных данных) автоматически сохранять их извне. Я просмотрел примечания к выпуску и не нашел ничего, что говорило бы, что вы не можете использовать эту функцию с iCloud. Это может быть самое простое решение.

person Richard Warren    schedule 08.03.2012

На данный момент атакую ​​побочную точку (так как у меня не было НИКАКОГО хорошего опыта работы с UIManagedDocument).

Вы можете сохранить двоичный файл внутри Core Data для приложения iOS 5.0+, используя ссылку на внешний файл. Затем вы можете напрямую сохранить PNG изображения в Core Data и не беспокоиться о UIManagedDocument или раздувании файла sqlite.

Ничто не мешает вам хранить PNG вместо UIImage.

person Marcus S. Zarra    schedule 29.02.2012
comment
Спасибо. Поместит ли это содержимое внутри PNG внутрь UIManagedDocument? - person Jorge Ortiz; 29.02.2012
comment
Если вы использовали UIManagedDocument, тогда да. Однако вы также можете попробовать сделать это без UIManagedDocument и посмотреть, что произойдет. Я все еще сомневаюсь в необходимости UIManagedDocument во всех случаях, кроме самых необычных. - person Marcus S. Zarra; 29.02.2012
comment
Возможность использовать iCloud для обмена документами с другими пользователями, которые не используют ту же учетную запись iCloud, является моей мотивацией. - person Jorge Ortiz; 01.03.2012
comment
Мне любопытно, как вы собираетесь это делать. Используя прямую реализацию Core Data, вы можете синхронизироваться с iCloud, поэтому мне любопытно, какую разницу вы используете в UIManagedDocument. - person Marcus S. Zarra; 01.03.2012
comment
Чтобы поделиться документом с другим пользователем и позволить другому пользователю иметь оба документа, решение Core Data + iCloud не работает. План состоит в том, чтобы поделиться URL-адресом через URLForPublishingUbiquitousItemAtURL: expirationDate: error :, но для этого требуется инкапсуляция в оболочку UIDocument (подкласса). - person Jorge Ortiz; 02.03.2012
comment
Ах, это интересная идея. Спасибо, что поделились. - person Marcus S. Zarra; 02.03.2012
comment
@ MarcusS.Zarra У вас все еще есть проблемы с UIManagedDocument? Вначале у меня был плохой опыт, но после того, как я его получил, он кажется действительно приятным. Я глубоко уважаю вас (у меня есть ваши книги и видеоролики iDeveloper.tv), поэтому после прочтения я задаюсь вопросом, чего мне не хватает. - person Jody Hagins; 18.04.2012
comment
Спасибо :) Мое мнение о UIManagedDocument не изменилось, хотя я подозреваю, что большая часть этого лежит на плечах iCloud. UIManagedDocument многое отвлекает и делает вещи непрозрачными на мой вкус. iCloud все еще определенно груб. - person Marcus S. Zarra; 18.04.2012

Еще одна мысль. Возможно, вам понадобится использовать NSFileCoordinator для операций чтения и записи. Технически для любых операций чтения или записи в контейнере iCloud необходимо использовать координатор файлов (для координации со службой синхронизации iCloud - это предотвращает случайное повреждение файла, читая его, пока другой процесс записывает в него).

Я знаю, что UIDocument автоматически обертывает большинство своих методов ввода и вывода. Я предполагаю, что эти методы обернуты аналогичным образом (поскольку они дают вам URL-адрес для использования). Однако документы не очень понятны.

person Richard Warren    schedule 08.03.2012
comment
После повторного чтения документов UIDocument выполняет скоординированное чтение и запись файлов документов, которые автоматически интегрируются с облачными службами. Но для writeAdditionalContent: toURL: originalContentsURL: error: который вызывается как часть writeContents: andAttributes: SafeToURL: forSaveOperation: error: он утверждает, что чтение и запись данных документа [...] должны быть скоординированы с другими попытками чтения из и записать в тот же файл документа. Как вы сказали, совсем непонятно. Есть ли способ проверить, требуется ли это? - person Jorge Ortiz; 12.03.2012