The goals of this chapter are to describe the application that you will build, then to create the Xcode project and to understand the basics of what the Xcode project template gives you.
The goal of this tutorial is to provide a practical introduction to the Core Data framework and how you use it.
The aim here is not to create a polished application, but rather to illustrate the fundamental classes, tools, and techniques you’ll use in any Core Data–based program. It doesn’t provide in-depth explanations of all the features the framework offers, but it does give references to other documents you can read to gain a deeper understanding.
To add a bit more interest, the tutorial also makes use of the Core Location framework. The Core Location manager is a straightforward object, and for the purposes of this project you don’t need to understand it in any detail.
The application you create is conceptually simple—it lets you record your location at any time as an “event,” and uses a table view to show the time, latitude, and longitude of all the events you’ve recorded. It has an Add button to add a new event, and an Edit button that allows you to delete events from the list.
In this tutorial, you use Core Data primarily to represent the
Event objects and store them in an external file so that they can be displayed when the application launches.
Create the Project
The only steps in this chapter are to create the project itself and link against the Core Location framework.
>> In Xcode, create a Project using the Window-Based Application template in the iOS section. In the Options section, select the switch to use Core Data for storage. Call the project “Locations”.
It’s important that you call the project “Locations” if you want to copy and paste code required later in the tutorial.
>> link the project against the Core Location framework.
Understanding a Core Data–Based Project
Together with various other supporting files, the template provides you with:
An application delegate class
A MainWindow interface (
A Core Data model (
.xcdatamodeld) file—typically referred to as the managed object model
The application also links against the Core Data framework.
Of the resources, the first two should be familiar, although the details of the delegate class will be new. The model file is described later in “Managed Object and Model.” For now, examine the header file of the application delegate class. In addition to the standard window and view controller, it provides (amongst other features) three properties and two methods:
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (NSURL *)applicationDocumentsDirectory;
As its name implies, the
applicationDocumentsDirectory method simply returns the URL identifying the application’s documents directory, which is where the file containing the application’s data will be located. The properties provide access to what’s called the Core Data stack, and
saveContext saves changes you make to model objects to the data file.
The Core Data Stack
Stack is the term used to describe a collection of Core Data framework objects that work together to get modeled objects from and save data to a persistent store—the file where your data is stored. Conceptually, a persistent store is like a database, with tables and records. (One of the store types you can use with Core Data is SQLite, but the store doesn’t have to be an actual database.)
Figure 1-1 shows the simplest—and most common—configuration of the stack.
The objects you usually work directly with are at the top of the stack—the managed object context and the managed objects it contains.
Managed Objects and the Managed Object Context
A managed object is an instance of
NSManagedObject or of a subclass of
NSManagedObject. Conceptually, it’s an object representation of a record in a table in a database, so it’s a model (in the sense of the model-view-controller design pattern) object that is managed by Core Data. Managed objects represent the data you operate on in your application—for example departments and employees in a human resources application; shapes, text areas, and groups in a drawing application; albums, artists, and tracks in a music management application. A managed object is always associated with a managed object context.
The managed object context is an instance of
NSManagedObjectContext. A context represents a single object space, or scratch pad, in an application. Its primary responsibility is to manage a collection of managed objects. These objects form a group of related model objects that represent an internally consistent view of one or more persistent stores. The context is a powerful object with a central role in your application, with responsibilities from life-cycle management to validation, relationship maintenance, and undo/redo.
When you create a new managed object, you insert it into a context. You fetch existing records in the database into the context as managed objects. (Fetching is discussed in greater detail in “Fetching Events.”) Any changes you make (whether insertion or deletion of complete objects, or manipulation of property values) are kept in memory until you actually commit them to the store by saving the context.
Figure 1-2 illustrates a managed object context that contains two managed objects corresponding to two records in an external database. In one of the objects, a property value has been changed in memory, but the change has not been committed to the database. Notice that there are two additional records in the database for which there are no corresponding managed objects.
The Managed Object Model
A managed object model is an instance of
NSManagedObjectModel. It’s an object representation of a schema that describes your database, and so the managed objects you use in your application. A model is a collection of entity description objects (instances of
NSEntityDescription). An entity description describes an entity (a table in a database) in terms of its name, the name of the class used to represent the entity in your application, and what properties (attributes and relationships) it has.
Figure 1-3 illustrates the relationship between an entity description in a model, a table in the database, and a managed object corresponding to a single record in the table.
Every managed object has a reference to the entity of which it is an instance.
Core Data uses the model to map between managed objects in your application and records in the database. It’s important to be aware that if you change the schema in your application, Core Data won’t be able to read stores you created using the previous model. (This is something common to many persistence mechanisms. Core Data, though, does also provide an infrastructure for managing such changes—see the Core Data Model Versioning and Data Migration Programming Guide.)
Persistent Store Coordinator
The persistent store coordinator plays a central role in how Core Data manages data; however, you don’t often interact with the coordinator directly when you use the framework. This section describes the persistent store coordinator in detail, so if you prefer you can skip it and refer to it later as necessary. (The persistent store coordinator is also described in “Core Data Basics” in the Core Data Programming Guide.)
A persistent store coordinator is an instance of
NSPersistentStoreCoordinator. It manages a collection of persistent object stores. A persistent object store represents an external store (file) of persisted data. It’s the object that actually maps between objects in your application and records in the database. There are different classes of persistent object store for the different file types that Core Data supports. You can also implement your own if you want to support a custom file type—see Atomic Store Programming Topics. To learn more about persistent stores and the different types, see “Persistent Store Features” in Core Data Programming Guide.
In an iOS application, you generally just have a single store, but in complex applications (particularly for Mac OS X) there may be several, each potentially containing different entities. The persistent store coordinator’s role is to manage these stores and present to its managed object contexts the façade of a single unified store. When you fetch records, Core Data retrieves results from all of them (unless you specify which store you’re interested in).
In any application, you might have multiple managed object contexts. You might want to maintain discrete sets of managed objects and edits to those objects; or you might want to perform a background operation using one context while allowing the user to interact with objects in another. Each of these would be connected to the same coordinator.
Figure 1-4 illustrates the role the coordinator plays. Stacks aren’t usually this complicated.
© 2012 Apple Inc. All Rights Reserved. (Last updated: 2012-12-13)