Include Core Data into your project is to include the umbrella header file:
#import <CoreData/CoreData.h>
To be able to work with Core Data, you need to understand that a Core Data stack is based on the following concepts:
- Persistent store: The object that represents the actual data base on disk. We never use this object directly.
- Persistent store coordinator: The object that coordinates reading and writing of information from and to the persistent store. The coordinator is the bridge between the managed object context and the persistent store.
- Managed object model (MOM): This is a simple file on disk that will represent our data model. Think about it as your
database schema
. - Managed object: This class represents an entity that we want to store in Core Data. Traditional database programmers would know such entities as
tables
. A managed object is of typeNSManagedObject
, and its instances are placed on managed object contexts. They adhere to the schema dictated by the managed object model, and they get saved to a persistent store through a persistent store coordinator. - Managed object context (MOC): This is a virtual board. That sounds strange, right? But let me explain. We create Core Data objects in memory and set their properties and play with them. All this playing is done on a managed object context. The context keeps track of all the things that we are doing with our managed objects and even allows us to undo those actions. Think of your managed objects on a context as toys that you have brought on a table to play with. You can move them around, break them, move them out of the table, and bring new toys in. That table is your managed object context, and you can save its state when you are ready. When you save the state of the managed object context, this save operation will be communicated to the persistent store coordinator to which the context is connected, upon which the persistent store coordinator will store the information to the persistent store and subsequently to disk.
If you check the relevant box of "Use Core Data" in the process of creating a new project, your app delegate will have some new properties and methods(with fully implementation):
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;
####1. Creating a Core Data Model with Xcode:
- Find the file with the extension of xcdatamodel in your application bundle in Xcode and click it to open the visual data editor
- Entity: Corresponds to a table in a database
- Attribute: Corresponds to a column in a table
- Click:
Add Entity
button on the bottom panel.
####2. Generating Class Files for Core Data Entities
- Create a new class: [New File...] - [iOS - Core Data] - [NSManagedObject subclass], and [Next]
- On the next screen, choose the
managed object model
that you want to save to disk and ensure it is ticked.(linked with you.xcdatamodeld
file) - And next, pick the entities that you want to export from your model on disk as Objective-C files
- and .... There you go! We turned our managed object into a real definition and implementation.!
When you create your data model using the editor in Xcode, you are creating the data relationships, entities, attributes, and so forth. However, to be able to use your model in your app, you must generate the code for your model. If you view the .h and .m files for your entities, you will realize that all the attributes are assigned dynamically. You can even see the @dynamic directive in the .m file of your entities to tell the compiler that it will fulfill the request of each attribute at runtime using dynamic method resolution.
####3. Creating and Saving Data Using Core Data
-
Import the entities class header before instantiate it(This is similar to creating a new row (managed object) in a table (entity) in a database (managed object context):
#import "Person.h"
-
Use the
insertNewObjectForEntityForName:inManagedObjectContext:
class method ofNSEntityDescription
to create a new object of a type specified by the first parameter of this method.After you are done, save your managed object context using thesave:
instance method of the managed object context. )Person *newPerson = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.managedObjectContext]; if (newPerson != nil) { newPerson.firstName = @"Anthony"; newPerson.lastName = @"Robbins"; newPerson.age = @51; NSError *savingError = nil; if ([self.managedObjectContext save:&savingError]) { return YES; } else { NSLog(@"Failed to save the new person. Error = %@", savingError); } }
-
Attempting to insert an unknown entity into a managed object con‐ text will raise an exception of type NSInternalInconsistencyExcep tion. After inserting a new entity into the context, we must save the context. This will flush all the unsaved data of the context to the persistent store.
####4. Reading Data from Core Data
Use an instance of NSFetchRequest
to read the contents of your entities (tables) using Core Data.
// Tell the request that we want to read the contents of the Person entity
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]
initWithEntityName:@"Person"];
NSError *requestError = nil;
// And execute the fetch request on the context
NSArray *persons = [self.managedObjectContext executeFetchRequest:fetchRequest
error:&requestError];
// Make sure we get the array
if ([persons count] > 0){
/* Go through the persons array one by one */
} else {
NSLog(@"Could not find any Person entities in the context.");
}
For those of you who are familiar with database terminology, a fetch request is similar to a SELECT
statement. In the SELECT
statement, you specify which rows, with which conditions, have to be returned from which table. With a fetch request, we do the same thing. We specify the entity (table) and the managed object context (the database layer). We can also specify sort descriptors for sorting the data we read.
####5. Deleting Data from Core Data
Use the deleteObject:
instance method of NSManagedObjectContext:
to delete a managed object (a row in a table) from a managed object context (your database).
Person *lastPerson = [persons lastObject];
[self.managedObjectContext deleteObject:lastPerson];=
if ([lastPerson isDeleted]) {
NSLog(@"Successfully delete the last person in the array");
NSError *savingError = nil;
if ([self.managedObjectContext save:&savingError]) {
NSLog(@"Successfully deleted the last person in the array.");
} else {
NSLog(@"Failed to deleted the last person in the array.");
}
}
This method doesn’t return an error to you in any of its parameters, nor does it return a BOOL value, so you really have no good way of knowing whether an object was successfully deleted using the managed object context. The best way to determine this is to use that managed object’s isDeleted
method.
####6. Sorting Data in Core Data
Create instances of NSSortDescriptor
for each attribute (column, in the database world) of an entity that has to be sorted. Add the sort descriptors to an array and assign the array to an instance of NSFetchRequest
using the setSortDescriptors:
instance method.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]
initWithEntityName:@"Person"];
NSError *requestError = nil;
NSSortDescriptor *ageSort = [[NSSortDescriptor alloc] initWithKey:@"age"
ascending:YES];
fetchRequest.sortDescriptors = @[ageSort];
NSArray *persons = [self.managedObjectContext executeFetchRequest:fetchRequest
error:&requestError];
if ([persons count] > 0){
/* Go through the persons array one by one */
} else {
NSLog(@"Could not find any Person entities in the context.");
}
An instance of NSFetchRequest can carry with itself an array of NSSortDescriptor instances. Each sort descriptor defines the attribute (column) on the current entity that has to be sorted and whether the sorting has to be ascending or descending.
You can assign more than one sort descriptor to one fetch request. The order in the array determines the order in which descriptors are provided. In other words, The output is sorted according to the first descriptor of the array, and within that order, entries are sorted according to the second descriptor of the array, etc.
NSFetchedResultsController: You use a
fetched results controller
to efficiently manage the results returned from a Core Data fetch request to provide data for aUITableView
object.Construct a fetched results controller using
initWithFetchRequest:managedObjectContext:sectionNameKeyPath:cacheName:
UITableViewDelegate Methods:
NSFetchedResultsControllerDelegate methods