Introduction to Core Data

Core Data is a framework that allows programmers to store their data in an object-oriented way. Core Data interacts with a persistent store at a low level.With Xcode you can choose to integrate Core Data into your project. In this tutorial we will insert some iOS Books as Core Data.

Open Xcode and create a new Empty Application. For product name, use CoreDataDemo and then fill out the Organization Name, Company Identifier and Class Prefix fields with your customary values. Make sure only iPhone is selected in Devices, and that the Use Core Data and Use Automatic Reference Counting checkbox are selected.

If you look in AppDelegate.h you see there are some properties created. The properies are:

  • Managed object context - bridge between the programmer and the managed object model
  • Managed object model - This represents the tables in a database
  • Persistent store coordinator - this is the connection between the physical file and the application

Select the CoreDateDemo.xcdatamodeld file. Press the "Add Entity" button and name the entity Book.Add the following Attributes:

  • isbn - type: String
  • title - type: String

Add a New File. Select iOS -> Core Data -> NSManaged Subclass

This will create the Book class from our previously created entity. Next, we will add a ViewController to the projects which will be filled with our book values later on. Create a new File -> Objective C Class. Name the class BookListViewController as a subclass of UIViewController.

In AppDelegate.h add a BookListViewController class and a property

@class BookListViewController; 

@property (strong, nonatomic) BookListViewController *bookListViewController;

Go to AppDelegate.m and change the application:didFinishLaunchingwithOptions to:

#import "BookListViewController.h"

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.bookListViewController = [[BookListViewController alloc] initWithNibName:nil bundle:nil];

self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];

self.window.rootViewController = self.bookListViewController; return YES;

The BookListViewController is assigned to the window's rootViewController.

In our BookListViewController we will use a FetchedResultsController. A fetched results controller can read managed objects from a managed object context and separate them into sections and rows. When you change a manged object, the modified object is instantly available to the fetchedController. Go to ListViewController.h and  change it in:

@interface BookListViewController : UIViewController  <UITableViewDataSource, UITableViewDelegate, NSFetchedResultsControllerDelegate>

@property (nonatomic, strong) UITableView *tableViewBooks;
@property (nonatomic, strong) NSFetchedResultsController *booksFRC;


We create a tableview and a fetched result controller property. Next, let's setup the framework for our view controller. Go to BookListViewController.m and change viewDidLoad in:

- (void)viewDidLoad 
[super viewDidLoad];

self.title = @"iOS Books";
self.tableViewBooks = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
self.tableViewBooks.delegate = self;
self.tableViewBooks.dataSource = self;

[self.view addSubview:self.tableViewBooks];

Add the following delegate methods, we will change them later on

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
return 0;

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
return nil;

Build and Run, you should see a empty table view

Add a helper method to create new book objects in BookListViewController.m

- (BOOL)createNewBookWithTitle:(NSString *)title isbn:(NSInteger)isbn 
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext;

BOOL result = NO;

Book *newBook = [NSEntityDescription insertNewObjectForEntityForName:@"Book" inManagedObjectContext:managedObjectContext];

if (newBook == nil) {
NSLog(@"Failed to create the new Book");
return NO; }

newBook.title = title;
newBook.isbn = [NSNumber numberWithInteger:isbn];

NSError *Error = nil;

if ([managedObjectContext save:&Error]) {
return YES; }
else {
NSLog(@"Failed to save the new book. Error = %@", Error);

return result;

Add managedObjectContext method

- (NSManagedObjectContext *)managedObjectContext
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *managedObjectContext = appDelegate.managedObjectContext;

return managedObjectContext;

Change initWithNibName:bundle in


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

if (self) {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Book" inManagedObjectContext:self.managedObjectContext];
NSSortDescriptor *isbnSort = [[NSSortDescriptor alloc] initWithKey:@"isbn" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:isbnSort, nil];
fetchRequest.sortDescriptors = sortDescriptors;
fetchRequest.entity = entity;

self.booksFRC = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self managedObjectContext] sectionNameKeyPath:nil cacheName:nil];
self.booksFRC.delegate = self;

NSError *Error = nil;

if ([self.booksFRC performFetch:&Error]) {
NSLog(@"Successfully fetched.");
} else {
NSLog(@"Failed to fetch.");
return self;

Here the Core Data objects will be fetched (is a sort of SELECT statement in a database) and the results are sorted by isbn number. Implement the tableView:numberOfRowsInSection method

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
id sectionInfo = [self.booksFRC.sections objectAtIndex:section];

return [sectionInfo numberOfObjects];

Here the number of fetched sections are returned. Next, implement the tableview:cellForRowAtIndexPath method.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
UITableViewCell *result = nil;

static NSString *BookTableViewCell = @"BookTableViewCell";
result = [tableView dequeueReusableCellWithIdentifier:BookTableViewCell];

if (result == nil) {
result = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:BookTableViewCell];
result.selectionStyle = UITableViewCellSelectionStyleNone; }

Book *book = [self.booksFRC objectAtIndexPath:indexPath];
result.textLabel.text = book.title;
result.detailTextLabel.text = [NSString stringWithFormat:@"ISBN: %lu", (long)[book.isbn integerValue]];

return result;

The textlabel and detail textlabel of the tableview will be filled with the book title and ISBN number.

Now that all methods are ready, Add the following lines to the viewDidLoad method.

[self createNewBookWithTitle:@"iOS Programming: The Big Nerd Ranch Guide" isbn:@"0321821521"];
[self createNewBookWithTitle:@"Programming in Objective C" isbn:@"0321811909"];
[self createNewBookWithTitle:@"iOS Hacker's Handbook" isbn:@"1118204123"];

One last thing to do is to implement the delegate method of the fetched result controller.

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
[self.tableViewBooks reloadData];

When there are new items fetched, this will reload the table. Build and Run, You should see the Books and ISBN numbers in the tableview.

You can download the source code of the CoreDataDemo at the ioscreator repository on github.