【问题标题】:How do I save additional content into my UIManagedDocument file packages?如何将其他内容保存到我的 UIManagedDocument 文件包中?
【发布时间】:2012-01-11 05:22:23
【问题描述】:

我在破译Apple's documentation around 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 文件我的持久存储中的路径。

【问题讨论】:

  • 你有什么运气吗?我也在研究同样的事情。

标签: ios cocoa-touch core-data uidocumentinteraction


【解决方案1】:

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

你知道的越多……

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

【讨论】:

    【解决方案2】:

    感谢 Apple DTS 帮助我理解这门课。我在这里分享了他们帮助我的一些示例(稍作修改)。

    好的,所以基本上它是这样工作的:子类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];
    

    目前,我没有将它用于图像和视频 - 但该示例应该足以让您开始使用。

    【讨论】:

    • 太好了,谢谢!我唯一不确定的是处理将附加到文档的文件(例如照片、mp3 等)。这一切都是通过将文件访问协调到文档文件包装器的附加内容目录中手动完成的吗?
    • 所以基本上我要处理的方法是将任意文件的 NSURL 读/写到附加到 UIManagedDocument 子类的数组中。当调用readAdditionalContentFromURL:error: 方法时,获取磁盘上的 URL 列表并将其存储。每当调用writeAdditionalContent:toURL:originalContentsURL:error: 时,您可能需要将某种形式的缓存与您刷新的子类相关联,以便将照片/mp3s/等实际写入磁盘。您可能会选择将文件存储在临时目录中,直到发生此刷新。
    • 我看不到一个非常干净的方法来做到这一点,所以考虑到我针对这个项目的目标是 iOS 5 及更高版本,我在我的核心数据存储中启用了二进制属性的外部存储,然后我推送图像和视频进入我的持久存储而不是附加内容目录。到目前为止,这是一个合理的折衷方案,我还没有看到任何性能或行为问题(我知道其他人有外部存储)。抱歉,这不是一个完美的答案,但就像 iCloud 添加的许多 API 一样,我认为 Apple 还没有完成记录^H^H^H^H^H^H^H^H^H^H^H 它们.
    • 还是看不懂:(。如何保存和删除附加内容中的文件。可以举个例子吗?
    • 如果附加内容是NSFileWrapper,写的时候要不要使用atomic选项?见this question
    猜你喜欢
    • 2013-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    • 2020-11-23
    • 2015-02-05
    • 2021-12-22
    • 2010-10-05
    相关资源
    最近更新 更多