Setting Up Default Data
When a Core Data project is first set up, there is no data in it. Although this might work for some use cases, frequently it is a requirement to have some data prepopulated in the app for the first run. In the sample app there is a custom data setup class called ICFDataStarter, which illustrates how to populate Core Data with some initial data. A #define variable is set up in MyMovies-Prefix.pch called FIRSTRUN, which can be uncommented to have the app run the logic in ICFDataStarter.
Inserting New Managed Objects
To create a new instance of a managed object for data that does not yet exist in your model, a reference to the managed object context is needed. The sample app uses a constant to refer to the ICFAppDelegate instance, which has a property defined for the managed object context:
NSManagedObjectContext *moc = [kAppDelegate managedObjectContext];
To insert data, Core Data needs to know what entity the new data is for. Core Data has a class called NSEntityDescription that provides information about entities. Create a new instance using NSEntityDescription’s class method:
NSManagedObject *newMovie1 = [NSEntityDescriptioninsertNewObjectForEntityForName
:@"Movie"
inManagedObjectContext
:moc];
After an instance is available, populate the attributes with data:
[newMovie1setValue
:@"The Matrix"
forKey
:@"title"
]; [newMovie1setValue
:@"1999"
forKey
:@"year"
]; [newMovie1setValue
:@"Take the blue pill."
forKey
:@"movieDescription"
]; [newMovie1setValue
:@NO
forKey
:@"lent"
]; [newMovie1setValue
:nil
forKey
:@"lentOn"
]; [newMovie1setValue
:@20
forKey
:@"timesWatched"
];
Core Data uses key-value coding to handle setting attributes. If an attribute name is incorrect, it will fail at runtime. To get compile-time checking of attribute assignments, create a custom NSManagedObject subclass and use the property accessors for each attribute directly.
The managed object context acts as a working area for changes, so the sample app sets up more initial data:
NSManagedObject *newFriend1 = [NSEntityDescriptioninsertNewObjectForEntityForName
:@"Friend"
inManagedObjectContext
:moc]; [newFriend1setValue
:@"Joe"
forKey
:@"friendName"
]; [newFriend1setValue
:@"
joe@dragonforged.com
"
forKey
:@"email"
];
The last step after setting up all the initial data is to save the managed object context.
NSError *mocSaveError =nil
;if
([mocsave
:&mocSaveError]) {NSLog
(@"Save completed successfully."
); }else
{NSLog
(@"Save did not complete successfully. Error: %@"
, [mocSaveErrorlocalizedDescription
]); }
After the managed object context is saved, Core Data will persist the data in the data store. For this instance of the app, the data will continue to be available through shutdowns and restarts. If the app is removed from the simulator or device, the data will no longer be available. One technique to populate data for first run is to copy the data store from the app’s storage directory back into the app bundle. This will ensure that the default set of data is copied into the app’s directory on first launch and is available to the app.
Other Default Data Setup Techniques
There are two other default data setup techniques that are commonly used: data model version migrations and loading data from a Web service or an API.
Core Data managed object models are versioned. Core Data understands the relationship between the managed object model and the current data store. If the managed object model changes and is no longer compatible with the data store (for example, if an attribute is added to an entity), Core Data will not be able to initiate the persistent store object using the existing data store and new managed object model. In that case, a migration is required to update the existing data store to match the updated managed object model. In many cases Core Data can perform the migration automatically by passing a dictionary of options when instantiating the persistent store; in some cases, additional steps need to be taken to perform the migration. Migrations are beyond the scope of this chapter, but be aware that migrations can be used and are recommended by Apple to do data setup.
The other approach is to pull data from a Web service or an API. This approach is most applicable when an app needs to maintain a local copy of a subset of data on a Web server, and Web calls need to be written for the app to pull data from the API in the course of normal operation. To set up the app’s initial data, the Web calls can be run in a special state to pull all needed initial data and save it in Core Data.