





















































A fast-paced, example-driven guide guide to data-drive iPhone, iPad, and iPod Touch applications
Core Data is Apple's persistence framework, which is used to persist—store our application's data in a persistent store, which may be memory or a flat file database. It helps us represent our data model in terms of an object graph, establish relationships among objects, and it can also store object graphs on the disk. It also allows us to use the entities of our data model in the form of objects, that is, it maps our data into a form that can be easily stored in a database, such as SQLite, or into a flat file. Also, the Core Data reduces a lot of coding. On using Xcode's templates for Core Data applications, we automatically get the boilerplate code that does several complex tasks such as generating XML files, binary files, SQLite files automatically for us without writing a single code, allowing us to focus on the business logic of our application.
Besides this, Core Data also provides several features that are required in data manipulation, which includes filtering data, querying data, sorting data, establishing relationships with other data, and persisting data in different repositories.
The Core Data framework provides lots of features that include the following:
Core Data describes the data in terms of a data model. A data model is used to define the structure of the data in terms of entities, properties, and their relationships.
Because Core Data maintains data in terms of objects, an entity is an individual data object to represent complete information of the person, item, object, and so on. For example, customer is an entity, which represents information of customers, such as name, address, e-mail ID, contact number, products purchased, date of purchase, and so on. Similarly, the product is an entity, which represents the information of a product, such as name of the product, price, weight, and so on. An entity consists of properties that are a combination of attributes and relationships. An entity in Xcode's Data Model Editor may appear as shown in the following screenshot:
Properties of an entity give detailed information about it, such as what are its attributes and how it is related to other entities. A property of an entity refers to its attributes and relationships. Attributes are scalar values and relationships are pointers to or collections of other entities at the object level. A property is represented by a name and a type.
Attributes are the variables within an object (entity). In fact, a collection of attributes makes an entity. In database language, they are known as columns of the table. For example, the customer's entity may consist of attributes such as name, address, contact number, items purchased, and so on. Similarly, the attributes in the products table may be item code, item name, quantity, and so on. While creating attributes of an entity, we have to specify its name and its data type to declare the kind of information (whether integer, float, string, and so on) that will be stored in the attribute. Also, we can define the constraints on the information that can be stored in the column. For example, we can specify the maximum, minimum value (range) that can be stored in that attribute, or whether the attribute can or cannot store certain special symbols, and so on. Also, we can specify the default value of an attribute.
Besides attributes, an entity may also contain relationships (which define how an entity is related to other entities). The attributes and relationships of an entity are collectively known as properties. The relationships are of many types (To-One, To-Many, and Many-to-Many) and play a major role in defining connection among the entities and what will be the impact of insertion or deletion of a row in one entity on the connected entities.
Examples of relationship types:
To define a many-to-many relationship in Core Data, we have to use two To-many relationships. The first To-many relationship is set from the first entity to the second entity. The second To-many relationship is set from the second entity to the first entity.
In Xcode's Data Model Editor, the relationship from Customer to Product—a To-Many relationship—is represented by a line that appears pointing from the Customer entity to the Product entity with two arrows, (designating a One-to-Many relationship) as shown in the subsequent screenshot, whereas the To-One relationship is represented by a line with a single arrow:
When defining relationships in Core Data we may use inverse relationships, though it's optional.
In Core Data, every relationship can have an inverse relationship. Like, if there is a relationship from Customer to Product, there will be a relationship from Product to Customer too. A relationship does not need to be the same kind as its inverse; for example, a To-One relationship can have an inverse relationship of type To-Many. Although relationships are not required to have an inverse, Apple generally recommends that you always create and specify the inverse, (even if you won't need) as it helps Core Data to ensure data integrity.
For example, consider a situation when a Customer entity has a relationship of the To-Many type to a Product entity and some information of a customer is changed or a row of a customer is deleted. Then it will be easier for Core Data to ensure consistency; that is, by inverse relationship, Core Data can automatically find the products related to the deleted customer and hence, delete them too.
Before we go further, let us have a quick look at the architecture that is used in iPhone application development: MVC.
iPhone application development uses MVC architecture where M stands for Model, V stands for View, and C for Controller.
Core Data organizes the data model in terms of objects that are easy to handle and manipulate. The finalized objects are stored on a persistent storage. The usual way of representing data models is through classes that contains variables and accessor methods. We don't have to create classes by hand, (for our data models) as Core Data framework provides a special Data Model Design tool (also known as Data Model Editor) for quickly creating an entity relationship model. The terms that we will be frequently using from now onwards are Managed Object Model, Managed Objects, and Managed Object Context. Let us see what these terms mean:
All managed objects are registered with managed object context.
For an application, we need the information represented by the Managed Object (instance of an entity) to be stored on the disk (persistent store) via managed object context. To understand the concepts of managed object context and its relation with data persistence, we need to understand the components of Core Data API, so let us go ahead and look at what Core Data API is all about.
The Core Data API, also called the stack, consists of three main components:
The PersistentStoreCoordinator plays a major role in storing and retrieving managed objects from the Persistent Store via ManagedObjectContext. We can see in the following figure how the three are related:
The Managed Object Model (an instance of NSManagedObjectModel class) is created from the data model of our application. If there is more than one data model in our application, the Managed Object Model is created by merging all of the data models found in the application bundle. The managed object (instance of the NSManagedObject class or its subclass) represents an instance of an entity that is maintained (managed) by the Core Data framework. A managed object is an instance of an Objective-C class, but it differs from other objects in three main ways:
For working with a managed object, it is loaded into memory. The managed object context maintains the state of the managed object after it is loaded in memory. The Managed Object Context tracks in-memory changes that have yet to be persisted to the data store. Any changes made to the state of an NSManagedObject do actually affect the state of the object in memory, not just the persistent representation of that object in the data store. When we want to commit the modifications made to the managed object, we save the managed object context to the persistent store. In order to deal with persistent store, the managed object context needs a reference to a PersistentStoreCoordinator. In other words, a pointer to the PersistentStoreCoordinator is required for creating a Managed Object Context. Remember, the PersistentStoreCoordinator is the essential middle layer in the stack that helps in storing and retrieving the managed object model from the persistent store.
The managed object context is an object that plays a major role in the life cycle of managed objects. It handles all the aspects of managed object from faulting to validation including undo/redo. To modify managed objects, they are fetched from a persistent store through managed context. The modified managed objects are committed to the persistent store through context only. The managed objects represent data held in a persistent store. Faulting is considered to occur for an object whose property values have not yet been loaded from the external data store.
To access the objects (entity) in managed object context, FetchRequest, an instance of NSFetchRequest class, is used. To define the entity to be retrieved via NSFetchRequest, we pass the appropriate NSEntityDescription to the NSFetchRequest.
The result, that is, the set of entities retrieved from the managed object context (on the basis of FetchRequest) are managed by FetchedResultsController—an instance of NSFetchedResultsController.
In fact, FetchRequest is passed to the FetchedResultsController along with a reference to the managed object context. Once the NSFetchedResultsController class has been initialized, we can perform a fetch operation to load the entities (stored in it) into memory.
The managed object context keeps track of all the changes made to the managed object since the last time it was loaded in memory and hence helps in undoing any changes made to the managed object (if required).The Persistent Store Coordinator helps in avoiding redundancy if multiple calls are made by different classes on the same file at the same time, that is, the multiple calls are serialized by the NSPersistentStoreCoordinator class to avoid redundancy.
Let us now get a detailed understanding of the terms used above.