A common rule of thumb when saving images to a database. If the image is really small, then save it directly to the database, if it's big save it in a file and save the name of that file or path to the file in the database. With Core Data we don't have to bother with implementing either, it takes care of all the details by just selecting an option in the data model.
Modifying The Model
We can't save the image as an instance of UIImage
because Core Data doesn't have any knowledge of what that is. Instead we need to save images as binary type which means using iOS's Data
type.
In our case every Note
will have a PhotoFrame
and each PhotoFrame
might have a single imageData
. The imageData
property will be optional as it might be empty.
To create the relationship between Note
and PhotoFrame
we need to setup the properties and delete rules. We must uncheck Optional
as each Note
must have a PhotoFrame
and delete rule should be that when we delete a Note
we delete the PhotoFrame
so we change it to Cascade
In setting up the inverse relationship between the PhotoFrame
and the Note
the Optional
property should be false because we don't want a PhotoFrame
if it's not connected to a Note
. The delete rule should be Nullify
because when we delete a PhotoFrame
we don't want to do anything to the Note
.
Model Versions
If there were previously saves objects in the database you will get an error from xCode saying something about the store used to create the new model is not the same.
To fix this we need to create a new model version. To do this we select "Add Model Version" from the Editor tab. We can call it whatever we want.
After we create a new model version we can see it in the file navigator, but there is a problem because the old model version is still set to the current version.
To change the current model version select the Model.xcdatamodelId
in the file navigator and in the file inspector change the Model Version
selector.
Ideally we would create the new version first, but if we didn't we will need to add all the changes we made to the new version.
The last step is to make a minor change in our Core Data Stack file to make sure it performs the migration from version one to version two. By adding the code below create two options in the form of a dictionary and add them to the persistent store coordinator.
NSMigratePersistentStoresAutomaticallyOption
tells the coordinator to perform the migrations automatically.
NSInferMappingModelAutomaticallyOption
tells xCode to figure out how to make the migration from version one to version two happen.
// Options for migration
let options = [NSInferMappingModelAutomaticallyOption: true,NSMigratePersistentStoresAutomaticallyOption: true]
do {
try addStoreCoordinator(NSSQLiteStoreType, configuration: nil, storeURL: dbURL, options: options as [NSObject : AnyObject]?)
} catch {
print("unable to add store at \(dbURL)")
}