Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save images in Core Data + iCloud - Swift

My app is a mood diary and to save data I've chosen to use Core Data (for strings, images, etc.); to allow the user to restore his diary I've implemented iCloud, that works well with Core Data.

Everything works well if I have not much entries, but when the images saved are too much the app is slow to load data and encounters memory warnings.

To save my images I've chosen Transformable data type and not Binary Data; I know that is not the best way to save images (saving url is surely better), but I need to sync my data on iCloud, and saving images as Transformable allows me to sync data in a simple way (thanks to the possibility offered by Apple Api to link Core Data and iCloud).

What can I do to avoid this memory warnings and sync my app pics on iCloud?

I've considered the possibility to save my pics on a custom photo album (if iCloud is activated for Photo app my app pics would be synchronized), but I need to save them with custom name to retrieve them from camera roll to my app, and for the moment I don't find any solution to save pic with custom name in a custom photo album.

Saving photos in document directory (and saving urls in my core data entity) would be the right choice for local database, but my app pics would not be synchronized.

like image 515
RiccardoCh Avatar asked Aug 04 '15 10:08

RiccardoCh


1 Answers

There are a few things you can try.

First, add an image thumbnail property which stores a smaller version of the image. Use that whenever possible. Loading a bunch of full-size photos needs a lot of memory, so change to loading smaller images whenever your UI allows smaller sizes.

Beyond that you can change how you handle images using one of the following strategies. In ascending order of complexity (and effectiveness):

  1. Make sure "Allows external storage" is enabled for the image property in your data model. This will let Core Data put the images outside the persistent store without requiring you to manage those files. This will save on memory if, for example, you sometimes fetch data but aren't using the image property.

  2. Change the data model so that the image is saved in a different entity, with a relationship linking it to your current entity. This should make it easier to avoid "accidentally" loading images when you're not using them.

  3. Put the images in separate files and keep only the file names in Core Data. You can still sync the images via iCloud, because you can sync files directly via iCloud outside of Core Data. But you'll need extra code to manage uploading/downloading the images. You'll also need to make sure you can handle the case where Core Data has finished syncing but the image is not available yet.

On this list, #1 is easiest but will probably have the least effect. Using #3 should be very effective but will require the most work.

like image 116
Tom Harrington Avatar answered Sep 21 '22 22:09

Tom Harrington