Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Core Data for iOS Store in External Record File

Tags:

First time asking a question on here, so please go easy if I don't provide enough info. Basically part of my iOS app allows users to take a picture which will be stored in a Core Data store. The attribute is a Transformable type, and I have created an NSManagedObject subclass which I simply use to set its image attribute to the new image provided by the user.

I know storing large files in Core Data is a bad idea, which is why I was excited when I saw the "Store in External Record File" option under the image attribute in the Core Data entity. However, my app performance says otherwise, taking several seconds on an iPhone 5 to load only a few images (which I know doesn't sound like much time, but considering how powerful the iPhone 5 is, older devices would likely take much longer with the same data).

I've looked around, and some people say that the Store in External Record File option is only applicable to the OS X environment, even though it is available in an iOS app. However, I also saw this under Apple's "What's New in iOS 5" doc (it's the next to last item under Core Data, near the end):

Managed objects support two significant new features: ordered relationships, and external storage for attribute values. If you specify that the value of a managed object attribute may be stored as an external record, Core Data heuristically decides on a per-value basis whether it should save the data directly in the database or store a URL to a separate file that it manages for you.

So my question is, who's right? Is it true that Apple made a mistake in giving this option for iOS apps, and that it actually does nothing unless you're on the Mac, or does it actually do something and I'm not configuring it the right way, or is it doing what it's supposed to do and the performance is bad anyway?

I've seen some guides explaining how to store large files (like images) as files, and save the URL to them in the Core Data store instead, but since this is essentially what this new option is doing, or maybe should be doing, I'm not sure if following these guides would even help.

I'm really sorry if this has been asked before. Normally I'd be fine with figuring this out on my own, but Core Data is totally new to me, and I'm still not sure how I managed to squeak by the initial setup. Thank you for any help you can offer!

like image 275
kingsapo Avatar asked Apr 13 '13 04:04

kingsapo


People also ask

How does Core Data save Data?

Most interactions with Core Data will occur through an instance of NSManagedObjectContext : the portal through which our app will create new entities, save changes, and fetch from the store. The persistent container comes with a NSManagedObjectContext as one of its built-in properties.

What is iOS Core Data?

Core Data is an object graph and persistence framework provided by Apple in the macOS and iOS operating systems. It was introduced in Mac OS X 10.4 Tiger and iOS with iPhone SDK 3.0. It allows data organized by the relational entity–attribute model to be serialized into XML, binary, or SQLite stores.

Should I use Core Data iOS?

The next time you need to store data, you should have a better idea of your options. Core Data is unnecessary for random pieces of unrelated data, but it's a perfect fit for a large, relational data set. The defaults system is ideal for small, random pieces of unrelated data, such as settings or the user's preferences.

Why is Core Data used iOS?

Overview. Use Core Data to save your application's permanent data for offline use, to cache temporary data, and to add undo functionality to your app on a single device. To sync data across multiple devices in a single iCloud account, Core Data automatically mirrors your schema to a CloudKit container.


2 Answers

who's right ?

the iOS docset for the NSAttributeDescription class does mention the allowsExternalBinaryDataStorage and the setAllowsExternalBinaryDataStorage: methods so there is little chance that there is a mistake from Apple.

are you doing something wrong or is slow anyway ?

You said that

The attribute is a Transformable type

But Core Data has a Binary data type. Maybe only this one is linked to the external storage capability.

if that's not it, we don't have enough info here:

  • How many pictures do you store ?
  • What are their sizes ? 
  • Do you automatically fetch all the images ?

Also, the Apple doc states that:

Core Data heuristically decides on a per-value basis…

  • Did you use a migration or are you starting from scratch ?

You could have a look in your app's sandbox to see if your pictures are really saved outside of CoreData.

Hope this helps.

like image 110
teriiehina Avatar answered Sep 29 '22 07:09

teriiehina


Good question!

Check this post: Storing blobs in external location using built-in CoreData option

Apparently it should work. You should also try it in the simulator and inspect the application data folder to see if the folders are created as described (~/Library/Application Support/iPhone Simulator/... - you will figure out the rest of the path). Also you could inspect the sqlite file with the sqlite3 command to see if the binary data is in the database.

I haven't personally used this option as I would prefer to go for manually saving the images in a folder and store a reference to them in the database instead. This way it will be easier to create UIImage object from the file to be displayed, would have better control on what goes where and so on and so forth. Will take some extra labour though!

Hope that helps you out.

like image 25
Dimitar K Avatar answered Sep 29 '22 05:09

Dimitar K