将 QLPreviewController 与 Core Data 一起使用的正确方法

Correct way to use QLPreviewController with Core Data

我有 CoreData 应用程序,它在外部文件中存储一些 BLOB("allows external storage" 标志)。

文件是图像、PDF、excel 文件等。我想使用 QLPreviewController 预览它。但是它不支持从头开始的CoreData。所以,我应该先将文件复制到 tmp 文件夹。我相信应该有更好的方法来做到这一点。 有没有?

根据 QLPreviewItem 的文档,previewItemURL 返回的 URL 必须是文件 URL.

因此,对于磁盘上的文件,您必须能够为它指定 URL。 Apple 不提供获取外部存储数据的 URL 的官方方法。此外,无论如何,"smaller" 文件将作为 BLOB 存储在 SQL 数据库中。

两个最可行的选择是在需要时将内容复制到临时文件中,或者自己将文件存储在磁盘上,并保留 URL(或者更好...一个唯一标识符)在核心数据模型中。

我会选择第二种方法。

如果将文件存储在包含核心数据存储的目录的子目录中,则只需在数据库中保留一个 UUID。然后您可以识别该文件,即使您想将它移动到不同的位置,也不必去更改商店中的所有实体。

假设您在与持久存储相同的目录中有一个名为 "externalFiles" 的目录。

如果您使用特殊实体,则可以为特定项目添加两个简单属性(标识符和标题)。标识符可以是 NSUUID.

的字符串表示

您可能已经想到达 URL...

- (NSURL*)URL {
    // Separated on multiple lines for readability
    NSString *identifier = [self valueForKey:@"identifier"];
    NSURL *url = self.objectID.persistentStore.URL;
    url = [url URLByDeletingLastPathComponent];
    url = [url URLByAppendingPathComponent:@"externalFiles"];
    url = [url URLByAppendingPathComponent:identifier];
    return url;
}

然后您可以通过实现 previewItemURLpreviewItemTitle.

这两个方法使您的 NSManagedObject 子类符合 QLPreviewItem 协议
- (NSURL*)previewItemURL {
    return self.URL;
}

- (NSURL*)previewItemTitle {
    return self.title;
}

然后,您可以将核心数据实例传递给 QLPreviewControllerDataSource,因为它们现在可以被视为 QLPreviewItems。