user996142
user996142

Reputation: 2883

Correct way to use QLPreviewController with Core Data

I have CoreData app that stores some BLOBs in external files ("allows external storage" flag).

Files are images, PDFs, excel files etc. I wanna use QLPreviewController ti preview it. But it does not support CoreData from scratch. So, I should first copy file to tmp folder. I am sure there should be better way to do that. Does there is any?

Upvotes: 1

Views: 586

Answers (1)

Jody Hagins
Jody Hagins

Reputation: 28409

According to the documentation for QLPreviewItem the URL returned by previewItemURL must be a file URL.

Thus, you must be able to give it a URL for a file that lives on disk. Apple does not provide an official way to get the URL for data stored externally. Furthermore, "smaller" files would be stored as a BLOB in the SQL database anyway.

The two most viable options are to either copy the contents into a temporary file when needed, or store the file on disk yourself, and keep the URL (or better yet... a unique identifier) in the core data model.

I'd go with the second method.

If you store the files in a subdirectory of the directory containing your core data store, you can just keep a UUID in the database. You can then identify the file, even if you want to move it to a different location, and you don't have to go change all the entities in the store.

Let's say you have a directory named "externalFiles" in the same directory as your persistent store.

If you used a special entity, you could add two simple attributes (identifier and title) for the particular item. The identifier can be the string representation of NSUUID.

You will probably already want to get at the 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;
}

You can then make your NSManagedObject subclass conform to QLPreviewItem protocol by implementing the two methods previewItemURL and previewItemTitle.

- (NSURL*)previewItemURL {
    return self.URL;
}

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

And then, you can just pass your core data instances to the QLPreviewControllerDataSource because they can now be treated as QLPreviewItems.

Upvotes: 1

Related Questions