问题 如何将其他内容保存到我的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包中的“附加内容”目录中?我希望使用UUID作为文件名(具有正确的文件扩展名)将直接图像(PNG,JPEG等)和视频(m4v等)保存到此目录中,并将对这些单个文件的引用存储为 NSString 我的持久存储中的文件路径。


11182
2017-12-02 04:54


起源

你有运气吗?我正在研究同样的事情。 - Michael Waterfall


答案:


信用去 Apple DTS 帮助我理解这门课。我正在分享他们在这里帮助我的一些例子(略有修改)。

好的,所以基本上它的工作原理如下:子类 UIManagedDocument,并实现以下方法(其中 extraInfo property只是在我们的子类上实现的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];

目前,我并没有将它用于图像和视频 - 但这个例子应该足以让你满足。


12
2018-01-17 21:28



太好了,谢谢!我唯一不确定的是处理将附加到文档的文件(例如照片,mp3等)。这是通过协调文件访问文档的文件包装器的附加内容目录手动完成的吗? - Michael Waterfall
所以基本上我要处理的方法是将任意文件的NSURL读/写到附加到UIManagedDocument子类的数组中。当。。。的时候 readAdditionalContentFromURL:error: 调用方法,获取磁盘上的URL列表并存储它。您可能需要将某种形式的缓存与您每次刷新的子类相关联 writeAdditionalContent:toURL:originalContentsURL:error: 被称为实际将照片/ mp3s /等写入磁盘。您可以选择将文件存储在临时目录中,直到发生此刷新。 - Tony Arnold
我没有看到一个非常干净的方法来做到这一点,所以鉴于我针对这个项目我的目标是iOS 5及更高版本,我在我的Core Data商店中启用了二进制属性的外部存储,并将图像和视频推送到我的持久存储中而不是额外的内容目录。到目前为止,这是一个合理的妥协,我没有看到任何性能或行为问题(我知道其他人有外部存储)。对不起,这不是一个完美的答案,但是像iCloud中添加的很多API一样,我认为Apple没有完成记录^ H ^ H ^ H ^ H ^ H ^ H ^ H ^ H ^ H ^ H ^ H他们。 - Tony Arnold
仍然无法理解:(。如何保存和删除其他内容中的文件。是否可以举一些例子? - Shmidt
如果附加内容是 NSFileWrapper,我应该使用 atomic 写作时的选择?看到 这个问题。 - Colas


-additionalContentForURL的文档:error:表示返回nil应该发出错误信号。

  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,而不是UIManagedDocument看似期望的NSDictionary。嗯。

你懂得越多...

附:我想这取决于-writeContents:andAttributes的一天中的时间:...它曾经引发了一个抱怨期待NSDictionary的异常,但后来又抛出一个异常抱怨我没有传递给它一个NSData。我的眉毛不能以比现在更像Spock的方式提升。


3
2018-02-14 00:14