我应该在UIManagedDocument中使用NSFileWrappers吗?

时间:2012-02-29 00:55:43

标签: core-data icloud uimanageddocument nsfilewrapper

我正在尝试将一个plist和几个二进制文件(比如图像)存储为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

到目前为止,我已成功按照How do I save additional content into my UIManagedDocument file packages?中的说明操作,但是当我尝试添加二进制文件时,有一些我不知道该怎么做的事情。

  1. 我应该将URL / / path /文件yyyyMMdd -HHmmss.extdoc / AdditionalContent (与readAdditionalContentFromURL一起提供的默认值:错误:) 视为NSFileWrapper吗?与仅使用URL相比,是否有任何优点/缺点?我发现使用文件包装器更复杂,因为必须使用文件包装器访问器和NSCoder(我猜)读取plist,而文件,我必须存储Images目录的文件包装器然后获取相应的使用objectForKey的节点(我假设)。但是Apple的基于文档的iOS应用程序编程指南关于自定义格式而不是NSData或NSFileWrapper,请说明“请记住,您的代码必须复制UIDocument为您做的事情,因此您必须处理更复杂的问题,并且更大的错误可能性。“我误解了这个吗?
  2. 每个文档的默认值都声明为属性:setter修改映射plist的NSDictionary并将文档标记为已更新,并且getter使用正确的密钥访问字典。我如何公开读/写二进制文件的能力?我应该在UIManagedDocument的子类中添加一个方法吗? - (void)writeImage:(NSString *)uuid;和 - (UIImage *)readImage:(NSString *)uuid;并且我应该将这些数据保存在内存中,直到保存文档为止?怎么样?
  3. 假设NSFileWrapper是可行的方法,如果我打算将此文档用于iCloud ,我应该将文件协调器与文件包装器一起使用吗?如果是这样,怎么样?
  4. 非常感谢每个问题的任何源代码。谢谢。

    P.S。:我知道我可以在Core Data中保存一些二进制数据,但我对这个解决方案感到不舒服。除了其他原因之外,我宁愿存储图像文件的PNG数据,如果我想创建桌面应用程序,那么UIImage的序列化版本将与NSImage不兼容。

3 个答案:

答案 0 :(得分:1)

我想说,一般来说我更喜欢UIManagedDocument。它比原始核心数据有一些优势。例如,它会自动为您设置整个核心数据堆栈。它还为您设置嵌套的托管对象上下文,因此您可以获得免费的后台保存。这些都不是特别惊天动地,但是从很少的代码中可以获得很多功能。

我还没有保存其他信息......但这是我的想法。

首先,您不需要将新URL视为文件包装器。您应该只能对提供的URL执行常规文件操作。只需确保在additionalContentForURL中正确实现了所有内容:error:,writeAdditionalContent:toURL:originalContentsURL:error:和readAdditionalContentFromURL:error:。读和写操作需要是对称的。你可能应该在additionalContentsForURL中对数据进行快照:错误:这样一切都将以一种已知的良好状态保存(因为保存操作是异步的)。

作为替代方案,您是否考虑过在数据模型中使用Store in External Record File标志而不是手动保存?这应该强制Core Data(根据二进制数据的大小)自动将它们存储在外部。我查看了发行说明,但我没有看到任何说你不能在iCloud中使用此功能的内容。这可能是最容易解决的问题。

答案 1 :(得分:0)

暂时攻击一个侧面点(因为我没有任何UIManagedDocument的良好体验)。

您可以使用外部文件参考将二进制文件保存在iOS 5.0+应用程序的Core Data中。然后,您可以直接将图像的PNG保存到Core Data,而不必担心UIManagedDocument或关于sqlite文件膨胀。

没有什么可以阻止你存储PNG而不是UIImage。

答案 2 :(得分:0)

另一个想法。您可能需要使用NSFileCoordinator进行读写操作。从技术上讲,iCloud容器中的任何读取或写入操作都需要使用文件协调器(以便与iCloud同步服务协调 - 这可以防止在另一个进程写入文件时通过读取文件而意外损坏文件)。

我知道UIDocument会自动包装其大部分输入和输出方法。我猜这些方法是相似的包装(因为它们会给你一个使用的URL) - 但是,文档并不是很清楚。