Как сохранить дополнительный контент в мои файлы UIManagedDocument?

У меня много проблем с расшифровкой документации Apple вокруг UIManagedDocument, в частности следующие методы:

  • - (id)additionalContentForURL:(NSURL *)absoluteURL error:(NSError **)error
  • - (BOOL)readAdditionalContentFromURL:(NSURL *)absoluteURL error:(NSError **)error
  • - (BOOL)writeAdditionalContent:(id)content toURL:(NSURL *)absoluteURL originalContentsURL:(NSURL *)absoluteOriginalContentsURL error:(NSError **)error

Удалось ли кому-либо успешно сохранить дополнительный контент в каталоге "добавочный контент" в своих пакетах UIManagedDocument? Я хочу сохранить прямые изображения (PNG, JPEG и т.д.) И видео (m4v и т.д.) В этот каталог, используя UUID в качестве имен файлов (с правильным расширением файла) и сохраняя ссылки на эти отдельные файлы в виде файла NSString пути в моем постоянном хранилище.

Ответ 1

Кредит идет Apple DTS за то, что помог мне понять этот класс. Я делюсь некоторыми примерами, которые они мне помогли (немного измененными).

ОК, поэтому в основном он работает следующим образом: subclass UIManagedDocument и реализует следующие методы (где свойство extraInfo - это просто NSDictionary, реализованный в нашем подклассе):

- (BOOL)readAdditionalContentFromURL:(NSURL *)absoluteURL error:(NSError **)error
{
   NSURL *myURL = [absoluteURL URLByAppendingPathComponent:@"AdditionalInformation.plist"];
   self.extraInfo = [NSDictionary dictionaryWithContentsOfURL:myURL];
   return YES;
}

- (id)additionalContentForURL:(NSURL *)absoluteURL error:(NSError **)error
{
   if (!self.extraInfo) {
       return [NSDictionary dictionaryWithObjectsAndKeys: @"Picard", @"Captain", [[NSDate date] description], @"RightNow", nil];
   } else {
       NSMutableDictionary *updatedFriendInfo = [self.extraInfo mutableCopy];
       [updatedFriendInfo setObject:[[NSDate date] description] forKey:@"RightNow"];
       [updatedFriendInfo setObject:@"YES" forKey:@"Updated"];

       return updatedFriendInfo;
   }
}

- (BOOL)writeAdditionalContent:(id)content toURL:(NSURL *)absoluteURL originalContentsURL:(NSURL *)absoluteOriginalContentsURL error:(NSError **)error
{
   if (content) {
       NSURL *myURL = [absoluteURL URLByAppendingPathComponent:@"AdditionalInformation.plist"];
       [(NSDictionary *)content writeToURL:myURL atomically:NO];
   }

   return YES;
}

UIManagedDocument будет вызывать эти методы, когда это необходимо, автоматически сохраняя все, что вам нужно сохранить, в пакет документов внутри каталога AdditionalContent.

Если вам нужно принудительно сохранить, просто вызовите на свой экземпляр UIManagedDocument следующее:

[self updateChangeCount:UIDocumentChangeDone];

В настоящее время я не использую это для изображений и видео, но пример должен дать вам достаточно, чтобы уйти.

Ответ 2

Документация для -additionalContentForURL: error: указывает на то, что возвращающее нуль должно сигнализировать об ошибке.

  A return value of nil indicates an error condition. To avoid generating 
  an exception, you must return a value from this method. If it is not always
  the case that there will be additional content, you should return a sentinel value (for example, an NSNull instance) that you check for in
  writeAdditionalContent:toURL:originalContentsURL:error:.

Я переопределяю -writeContents:andAttributes:safelyToURL:forSaveOperation:error: для другой цели (делая некоторые вещи при первом сохранении нового документа), а вызов super вызывает богов NSException, потому что значение contents равно nil, а не NSDictionary, как кажется ожидаемым UIManagedDocument. Хм.

Чем больше вы знаете...

P.S. Я думаю, это зависит от времени суток с -writeContents: andAttributes:... Он однажды бросил исключение, жалуясь на ожидание NSDictionary, но позже написал исключение, жалуясь, что я не передал ему NSData. Моя бровь не могла быть поднята более Спокой, чем сейчас.