Simple Core Data tutorial in iOS

By | July 7, 2015

In this tutorial we will be making a simple application to save a person details using Core Data.

Here we will have two models or it can be said as Database tables – Model1 and Model2.

Below are the basic things about Core Data…

Core Data Stack

The key objects of the stack are the
1. managed object model,
2. the persistent store coordinator,
3. and one or more managed object contexts.

NSManagedObjectModel – compare the managed object model to the schema of a database, that is, it contains information about the models or entities of the object graph, what attributes they have, and how they relate to one another.

NSPersistentStoreCoordinator – NSPersistentStoreCoordinator object persists data to disk and ensures the persistent store(s) and the data model are compatible. It mediates between the persistent store(s) and the managed object context(s) and also takes care of loading and caching data.
Core Data has caching built in.

NSManagedObjectContext – The NSManagedObjectContext object manages a collection of model objects, instances of the NSManagedObject class.

Create a new project with the “Use CoreData” Checkbox checked in…

So your app delegate should have the following methods

#pragma mark - Core Data stack

@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

- (NSURL *)applicationDocumentsDirectory {
    // The directory the application uses to store the Core Data store file. This code uses a directory named "com.coderzheaven.CoreDataDemo" in the application's documents directory.
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

- (NSManagedObjectModel *)managedObjectModel {
    // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreDataDemo" withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return _managedObjectModel;
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    // The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it.
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }
    
    // Create the coordinator and store
    
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataDemo.sqlite"];
    NSError *error = nil;
    NSString *failureReason = @"There was an error creating or loading the application's saved data.";
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
        // Report any error we got.
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
        dict[NSLocalizedFailureReasonErrorKey] = failureReason;
        dict[NSUnderlyingErrorKey] = error;
        error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
        // Replace this with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
    
    return _persistentStoreCoordinator;
}


- (NSManagedObjectContext *)managedObjectContext {
    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }
    
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (!coordinator) {
        return nil;
    }
    _managedObjectContext = [[NSManagedObjectContext alloc] init];
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    return _managedObjectContext;
}

#pragma mark - Core Data Saving support

- (void)saveContext {
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil) {
        NSError *error = nil;
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
            // Replace this implementation with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }
}

In the Project Navigator on the left, you should see a file named Core_Data.xcdatamodeld. This is the data model of the application that’s compiled to a .momd file. It’s that .momd file that the managed object model uses to create the application’s data model.

Now we will create two models or Tables to work with.
Click on the CoreDataModel file in the navigator and you will see a window like the one below.

You can click on the “Add Entity” Button on the bottom to create new Models.

Here I have created two models – Model1 and Model2.
Model1 has name, place and a relation to the Model2.
Model2 has age and profession.
You can click on “Create Attribute” to create new member variables inside the Model.

Core Data Demo iOS

For saving the data you can use the Following code.

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    
    NSManagedObjectContext *context = [appDelegate managedObjectContext];
    NSManagedObject *personInfo = [NSEntityDescription
                                       insertNewObjectForEntityForName:@"Model1"
                                       inManagedObjectContext:context];
    [personInfo setValue:self.name.text forKey:@"name"];
    [personInfo setValue:self.place.text forKey:@"place"];
    
    NSManagedObject *otherInfo = [NSEntityDescription
                                  insertNewObjectForEntityForName:@"Model2"
                                  inManagedObjectContext:context];
    [otherInfo setValue:@"25" forKey:@"age"];
    [otherInfo setValue:@"Engineer" forKey:@"profession"];
    [personInfo setValue:otherInfo forKey:@"model2"];
    
    NSError *error;
    if (![context save:&error]) {
        NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
    }
    

For retrieving the data , use the below code.

 AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *context = [appDelegate managedObjectContext];
    NSError *error;
    
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription
                                   entityForName:@"Model1" inManagedObjectContext:context];
    [fetchRequest setEntity:entity];
    NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
    
    NSMutableString *allData = [NSMutableString new];
    for (NSManagedObject *info in fetchedObjects) {
        NSManagedObject *details = [info valueForKey:@"model2"];
        NSLog(@"Name: %@", [info valueForKey:@"name"]);
        NSLog(@"Place: %@", [info valueForKey:@"place"]);
        NSLog(@"Age: %@", [details valueForKey:@"age"]);
        [allData appendFormat:@"Name : %@\n", [info valueForKey:@"name"]];
        [allData appendFormat:@"Place : %@\n", [info valueForKey:@"place"]];
        [allData appendFormat:@"Age : %@\n", [details valueForKey:@"age"]];
        [allData appendFormat:@"Profession : %@\n", [details valueForKey:@"profession"]];
    }

You can download the complete source code from here.

Leave a Reply

Your email address will not be published. Required fields are marked *