iOS | iPhone | iPad | Tutorial on Developing Core Data Applications for Beginners

This tutorial will show you how to create a Core Data application for IOS 5 devices. Core Data offers a higher level of abstraction to data persistence than SQLite. In fact Core Data uses SQLite for the actual storage among other storage types, however Core Data is much more than just storage. Core Data provides the tools to design your data model for your app, akin to having an E/R tool. Core Data is the most widely used storage facility with Apple apps -- for both OSX and IOS.

This tutorial will walk you through the steps to create an IOS 5 app that uses Core Data for data persistence. The tutorial will also show you how to setup input screens and output screens to input new data and to display the stored data.

Before starting the tutorial proper, clarification on a couple of concepts will help your understanding and help your gasp the logic in the tutorial starting with the Basic Architecture

Basic Architecture


Core Data is organized into NSManagedObjects which corresponds to tables in a SQLite database or other data persistence types. These NSManagedObjects can be broken down into Entities, which can be associated with table in a database. Entities can have Attributes which loosely translates as columns. NSManagedObjects are origanized into a NSManagedObjectModel, which can have several Entities with Relationships. Finally a “Select” can be performed using a NSFetchedManagedObject using Predicates.

That was the very skinny. I will provide some code samples for each of these concepts

NSFetchedManagedObject


You retrieve NSManagedObjects using a NSFetchedManagedObject. You can display or work with a subset of the data that is in the store using a Predicate just like a regular query.
Here are the basic steps for using the NSFetchedManagedObject to retrieve data from the store.

  • Initialize a NSManagedObjectContext
  • Initialize a NSEntityDescription
  • Create a NSFetchedRequest
  • Add a predicate and or a sort order (optional)
  • Execute the request

NSManagedObjectContext


Tne NSManagedObjectContext is the open session with the persistence store. You create and initialize a NSManagedObjectContext before creating, updating, deleting NSManagedObjects and fetching records.

NSManagedObjectModel


The NSManagedObjectModel defines the Entities, Attributes, Relationships and Predicates. A NSManagedObjectModel is encapsulated in the xcdatamodelid file. In essence the NSManagedObjectModel is the schema for the application you will create or are creating.

Core Data Schema Editor
Core Data Schema Editor
Map View
Map View

NSManagedObject


NSManagedObjects represents Entities in the NSManagedObjectModel which in turn represent tables in a database like SQLite. These objects can act as a dictionary having a many attributes (columns) with most standard data types including blobs.

Entities
Entities are defined in the NSManagedObjectModel. You can think of them as tables in a database and other supported store types in Core Data. Each Entity has a name and a class that is defined at runtime or can be defined from the schema model as NSManagedObjects throught the XCode Edtor command: Create NSManagedObject Subclass...

Attributes
Attributes define the dimensions in an Entity. They have a data type that matches most standard data types, especially those supported by SQLite database, which is the most used persistence store used with Core Data. Attributes are the Entities properties along with Relationships.

Relationships
As mentioned Relationships define the relationship between Entities. Relationships support “to-one” and “to-many” relationships with Entities. Relationships can be optional and you can also configure any “delete” rules that may apply.

Predicates
Predicates can be akin to a select statement in a SQL query. You can define them either through the NSManagedObjectModel Schema designer or through Objective-C . Predicates have a special syntax and can be dynamic by using variables to define the predicate.

Templates for Core Data in IOS 5


The IOS 5 SDK provides two templates for creating Data Core applications. However this doesn’t limit you from choosing another template - it just means that you will need to write a lot more code and configuration if you don’t use the offered templates.

Utility Application
This template offers an application starting point with a main view and an alternate view. It offers the possibility to include Core Data functionality and will generate all the code and configuration to get you started.

Master-Detail View Application
This type of application generates a navigation view controller and detail view with an UITableView controller which can display data from a Core Data persistence store.

Tutorial


This is a quick tutorial to demonstrate how easy it is to use Core Data to capture data from an application.

Step 1 : Create Project
For this tutorial I will use the Utility application template. Leave the Core Data enabled. Name your project anything you like.

Create an Utility project
Create an Utility project

Step 2 : Create Core Data Schema
Once the project is created, you will notice that a file with the extension “xcdatamodeId” was created. This is the schema file where you will define your Entities, Attributes, Relationships and Predicates. Select it now.

Empty Core Data File
Empty Core Data File
Continents and Countries Entities
Continents and Countries Entities
Map View
Map View

Select the Entity node and click on the “Add Entity” button towards the bottom of the screen. For this tutorial I will create two Entities: Continent and Country. Note the Entity names must start a Capital letter. Next select each Entity in turn and either click on the “+” below the Attribute section or click on the “Add Attribute” button on the bottom of the screen. For each Entity add one Attribute “name” with a string data type

Finally add a relationship by selecting each Entity in turn. For the Continent, name the relationship “continents” and the destination should be the “Country” Entity. The inverse will be created once the “countries” relationship is created under Country.

We will use the default Predicate of “All” which is the default.

Step 3 : Create Input Screen
Next open the storyboard file and add two labels and two text fields and a button. Layout the screen as in the following screenshot. With the storyboard file open, click on the Assistant Editor to open the corresponding header file. Create IBOutlets for each field by holding down the “control” button dragging a connection line using the left mouse button from each field to the header file. In the corresponding popup, make sure the connection type is IBOutlet and enter a name for the connection like continentNameFld. Click on the “connect” button to add the code and create a connection. Repeat the process for the second field which can be named something like countryNameFld.

For the button, repeat the process, but change the connection type to “IBAction” and name it something like saveData.

Input Form
Input Form
Action and Outlets
Action and Outlets

Step 4 : Add Input Logic
To cap off this tutorial, we will add some code to the saveData method (or whatever) you named yours. Locate the method in the implementation file. Add the following code:

- (IBAction)saveData:(id)sender {
NSManagedObjectContext *cxt = [self managedObjectContext];
NSManagedObject *newContinent = [NSEntityDescription insertNewObjectForEntityForName:@"Continent" inManagedObjectContext:cxt];
[newContinent setValue:self.continentNameFld.text forKey:@"name"];
_continentNameFld.text = @"";

NSManagedObject *newCountry = [NSEntityDescription insertNewObjectForEntityForName:@"Country" inManagedObjectContext:cxt];
[newCountry setValue:self.countryNameFld.text forKey:@"name"];
_countryNameFld.text = @"";

NSError *err;
if (![cxt save:&err]) {
NSLog(@"An error has occured: %@", [err localizedDescription]);
}

}


As you can see the first line creates a NSManagedObjectContext as explained earlier. Next we create a new NSManagedObject for the Continent and Country Entities using the InsertNewObjectForEntityForName method of the NSManagedObject class.

Next we set the value which we get from each field in the ViewController using the setValue method and the forKey method. Finally we save the changes by calling the save method from our context object. If we are unable to save, we raise an error.

Step 5 : Test App
Click on the run button to launch the IOS 5 Simulator. Try entering a continent and country in the corresponding fields and click on the save button. Watch the log to see if any errors are raised as you step through the saveData method. If no errors were raised, the data was successfully saved to the database.

In Summary
Working with Core Data is very easy if you use a pre defined template. It is a bit more trickier if you build a Core Data app from scratch.

Other Core Data Tutorials

If you would like to explore more advanced topics on Core Data, read my tutorial on how to store and retrieve (fetch) binary data using images (UIImage). The " How To Store and Display Images in a Core Data iPhone App | iOS | iPad | UIImage " provides complete details on how to store UIImage images in Core Data and how to fetch them and display based on user selection.

kcbAppDelegate.h

//
//  kcbAppDelegate.h
//  TestCoreData
//
//  Created by Kevin Languedoc on 1/8/12.
//  Copyright (c) 2012 kCodebook. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface kcbAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;

@end

kcbAppDelegate.m

//
//  kcbAppDelegate.m
//  TestCoreData
//
//  Created by Kevin Languedoc on 1/8/12.
//  Copyright (c) 2012 kCodebook. All rights reserved.
//

#import "kcbAppDelegate.h"

#import "kcbMainViewController.h"

@implementation kcbAppDelegate

@synthesize window = _window;
@synthesize managedObjectContext = __managedObjectContext;
@synthesize managedObjectModel = __managedObjectModel;
@synthesize persistentStoreCoordinator = __persistentStoreCoordinator;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    kcbMainViewController *controller = (kcbMainViewController *)self.window.rootViewController;
    controller.managedObjectContext = self.managedObjectContext;
    return YES;
}
							
- (void)applicationWillResignActive:(UIApplication *)application
{
    /*
     Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
     Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
     */
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    /*
     Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
     If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
     */
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    /*
     Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
     */
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    /*
     Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
     */
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Saves changes in the application's managed object context before the application terminates.
    [self saveContext];
}

- (void)saveContext
{
    NSError *error = nil;
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != 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();
        } 
    }
}

#pragma mark - Core Data stack

/**
 Returns the managed object context for the application.
 If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
 */
- (NSManagedObjectContext *)managedObjectContext
{
    if (__managedObjectContext != nil)
    {
        return __managedObjectContext;
    }
    
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil)
    {
        __managedObjectContext = [[NSManagedObjectContext alloc] init];
        [__managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return __managedObjectContext;
}

/**
 Returns the managed object model for the application.
 If the model doesn't already exist, it is created from the application's model.
 */
- (NSManagedObjectModel *)managedObjectModel
{
    if (__managedObjectModel != nil)
    {
        return __managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"TestCoreData" withExtension:@"momd"];
    __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return __managedObjectModel;
}

/**
 Returns the persistent store coordinator for the application.
 If the coordinator doesn't already exist, it is created and the application's store added to it.
 */
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (__persistentStoreCoordinator != nil)
    {
        return __persistentStoreCoordinator;
    }
    
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"TestCoreData.sqlite"];
    
    NSError *error = nil;
    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&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. 
         
         Typical reasons for an error here include:
         * The persistent store is not accessible;
         * The schema for the persistent store is incompatible with current managed object model.
         Check the error message to determine what the actual problem was.
         
         
         If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory.
         
         If you encounter schema incompatibility errors during development, you can reduce their frequency by:
         * Simply deleting the existing store:
         [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]
         
         * Performing automatic lightweight migration by passing the following dictionary as the options parameter: 
         [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
         
         Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.
         
         */
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    
    
    return __persistentStoreCoordinator;
}

#pragma mark - Application's Documents directory

/**
 Returns the URL to the application's Documents directory.
 */
- (NSURL *)applicationDocumentsDirectory
{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

@end

kcbMainViewController.h

//
//  kcbMainViewController.h
//  TestCoreData
//
//  Created by Kevin Languedoc on 1/8/12.
//  Copyright (c) 2012 kCodebook. All rights reserved.
//

#import "kcbFlipsideViewController.h"

#import <CoreData/CoreData.h>

@interface kcbMainViewController : UIViewController <kcbFlipsideViewControllerDelegate>

@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (weak, nonatomic) IBOutlet UITextField *continentNameFld;
@property (weak, nonatomic) IBOutlet UITextField *countryNameFld;
- (IBAction)saveData:(id)sender;


@end

kcbMainViewController.m

//
//  kcbMainViewController.m
//  TestCoreData
//
//  Created by Kevin Languedoc on 1/8/12.
//  Copyright (c) 2012 kCodebook. All rights reserved.
//

#import "kcbMainViewController.h"

@implementation kcbMainViewController

@synthesize managedObjectContext = _managedObjectContext;
@synthesize continentNameFld = _continentNameFld;
@synthesize countryNameFld = _countryNameFld;

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
}

- (void)viewDidUnload
{
    [self setContinentNameFld:nil];
    [self setCountryNameFld:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
	[super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
	[super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

#pragma mark - Flipside View

- (void)flipsideViewControllerDidFinish:(kcbFlipsideViewController *)controller
{
    [self dismissModalViewControllerAnimated:YES];
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"listView"]) {
        [[segue destinationViewController] setDelegate:self];
    }
}

- (IBAction)saveData:(id)sender {
    NSManagedObjectContext *cxt = [self managedObjectContext];
    NSManagedObject *newContinent = [NSEntityDescription insertNewObjectForEntityForName:@"Continent" inManagedObjectContext:cxt];
    [newContinent setValue:self.continentNameFld.text forKey:@"name"];
    _continentNameFld.text = @"";
    
    NSManagedObject *newCountry = [NSEntityDescription insertNewObjectForEntityForName:@"Country" inManagedObjectContext:cxt];
    [newCountry setValue:self.countryNameFld.text forKey:@"name"];
    _countryNameFld.text = @"";

    NSError *err;
    if (![cxt save:&err]) {
        NSLog(@"An error has occurred: %@", [err localizedDescription]);
    }
    
}


@end

More by this Author


Comments 33 comments

ilhan 4 years ago

Firstly thanks for this nice tutorial. I have a navigation based application and i need to save JSON data to Core Data Model than retrieve data from there. Can you give me an idea about how to do that? I can parse the response of GET(mean i parse JSON) but can't add into Entities. Thanks


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

I would store my initial Parsed data from JSON into a NSMutableArray, then loop through the array to populate entities using code from above. "Seeding" Core Data is always an issue. I hope this helps.


mikeydcarroll67 4 years ago

I've read in the iOS5 Developer's Cookbook you could render Core Data in a UITableView, but haven't quite figured out that recipe yet.


Jeffwk 4 years ago

Hi,

I have followed your tutorial and it is really easy to understand:-)

I keep getting an error though, I have even copied and paster your code to see what I have done different.

It says:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Cannot create an NSPersistentStoreCoordinator with a nil model'

Anything I have done wrong?? I know I have, but maybe its something simple:-)

Cheers Jeff


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

Please check the AppDelegate file to make sure that the NSPersistentStoreCoordinator is created and initialized


Jeffwk 4 years ago

Hi again,

Yes it is definitely initialized - and it appears as often in my code as it does in yours.

Could it be because I remade my .xcdatamodeld file? Like I deleted the original one and remade it so I could practice:-)

Jeff


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

Yes, you could be missing the required methods in the AppDelegate:

Here is a sample AppDelegate file for CoreData:

@implementation klAppDelegate

@synthesize window = _window;

@synthesize managedObjectContext = __managedObjectContext;

@synthesize managedObjectModel = __managedObjectModel;

@synthesize persistentStoreCoordinator = __persistentStoreCoordinator;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

// Override point for customization after application launch.

klMainViewController *controller = (klMainViewController *)self.window.rootViewController;

controller.managedObjectContext = self.managedObjectContext;

return YES;

}

- (void)applicationWillResignActive:(UIApplication *)application

{

/*

Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.

Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.

*/

}

- (void)applicationDidEnterBackground:(UIApplication *)application

{

/*

Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.

If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

*/

}

- (void)applicationWillEnterForeground:(UIApplication *)application

{

/*

Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.

*/

}

- (void)applicationDidBecomeActive:(UIApplication *)application

{

/*

Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.

*/

}

- (void)applicationWillTerminate:(UIApplication *)application

{

// Saves changes in the application's managed object context before the application terminates.

[self saveContext];

}

- (void)saveContext

{

NSError *error = nil;

NSManagedObjectContext *managedObjectContext = self.managedObjectContext;

if (managedObjectContext != 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();

}

}

}

#pragma mark - Core Data stack

/**

Returns the managed object context for the application.

If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.

*/

- (NSManagedObjectContext *)managedObjectContext

{

if (__managedObjectContext != nil)

{

return __managedObjectContext;

}

NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];

if (coordinator != nil)

{

__managedObjectContext = [[NSManagedObjectContext alloc] init];

[__managedObjectContext setPersistentStoreCoordinator:coordinator];

}

return __managedObjectContext;

}

/**

Returns the managed object model for the application.

If the model doesn't already exist, it is created from the application's model.

*/

- (NSManagedObjectModel *)managedObjectModel

{

if (__managedObjectModel != nil)

{

return __managedObjectModel;

}

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreDataCountries" withExtension:@"momd"];

__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

return __managedObjectModel;

}

/**

Returns the persistent store coordinator for the application.

If the coordinator doesn't already exist, it is created and the application's store added to it.

*/

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator

{

if (__persistentStoreCoordinator != nil)

{

return __persistentStoreCoordinator;

}

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataCountries.sqlite"];

NSError *error = nil;

__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&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.

Typical reasons for an error here include:

* The persistent store is not accessible;

* The schema for the persistent store is incompatible with current managed object model.

Check the error message to determine what the actual problem was.

If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory.

If you encounter schema incompatibility errors during development, you can reduce their frequency by:

* Simply deleting the existing store:

[[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]

* Performing automatic lightweight migration by passing the following dictionary as the options parameter:

[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.

*/

NSLog(@"Unresolved error %@, %@", error, [error userInfo]);

abort();

}

return __persistentStoreCoordinator;

}

#pragma mark - Application's Documents directory

/**

Returns the URL to the application's Documents directory.

*/

- (NSURL *)applicationDocumentsDirectory

{

return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];

}

@end


Jeffwk profile image

Jeffwk 4 years ago

Cool - got it fixed, what the issue was that the line that contains : @"CoreDataExercisde" withExtension:@"momd"]; was set to @"TestCoreData withExtension:@"momd"]; once I changed that it was fine:-)

Thank you - great tutorial:-)


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

Super, well I am happy that you got worked out. There is nothing more frustrating then staring at code and not knowing where the problem is. Thanks for your kind feedback, I really appreciate it.


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

For some reason, you comments are not showing up in my notifications. I am deeply sorry because I strive to answer every comments. I have read part of the book. It has good examples. For Core Data, I strongly suggest using one of the templates in Xcode to get started.


Jeffwk profile image

Jeffwk 4 years ago

Just one more quick question - are you planning or do you already have a tutorial on how to display the result of this exercise in a UITableView?

Cheers Jeff


--Nick/ 4 years ago

@Jeffwk: To render Core Data in a table view, I've followed: http://timroadley.com/2012/02/09/core-data-basics-...


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

Hi Jeff,

Actually I am working on one. the code is complete, I just need to write up the instructions. I will finish this week. Thanks for the link. I am glad you were able to push through.

K


Giri 4 years ago

Nice tutorial.

Check below link for details about core data:

http://blog.tarams.com/?p=426


pengweisi 4 years ago

Hi,

Thanks for your tutorials they have helped me immensely. They are well developed and easy to follow. I was curious how you might add images to a core data base like you did in the SQLite tutorial with the wine. I have looked online and the explanations are varied and they seem much more complicated than the way the SQLite database manager in Firefox deals with it. Anyway I look forward to more tutorials.


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

This is quite easy. After defining an Entity, add an attribute and set the data type to Binary Data. This is equivalent to a Blob data type in SQLite, which as you know is the underlining storage facility.

If you give me a couple of days, I could together a simple tutorial on storing and displaying images using Core Data


pengweisi 4 years ago

Thank you I really appreciate your response. I would love to check out a tutorial on that. I'm slowly developing this app so no hurry. Thanks again for your time.


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

I am working on it, hopefully by the end of the week.... depending how my other stuff is moving along :)


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

Hi Jeff, pengweisi,

I have the code worked out for the CoreData/Binary Data (Image). I have a bug with displaying the stored binary in the detailviewcontroller and I have to finish writing the instructions. However, if you want the code as is which successfully browses the Resources folder and stores the images in Core Data and displays the listing in a table, send me an e-mail at kevinlanguedoc[at]gmail.com and I will send you the source code.

I will continue to debug the rest of the app (detail view controller) and write up the tutorial this week.

Cheers

Kevin


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

the new tutorial shows you how. See my last comment.

Kevin


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

Hi Jeff, pengweisi,

Actually, the Core Data for images app is fully functional. All that is needed is to write up the tutorial.

K


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

you're welcome. I should have the tutorial finished by the weekend.


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

Here is the tutorial on how to store and retrieve image or binary data using Core Data

https://turbofuture.com/misc/Core-Data-How-To-Stor...

Hope it helps


cherylvanhoorn profile image

cherylvanhoorn 4 years ago from Sydney

Great piece. I am one of the technically challenged and this helps a great deal.


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

Glad to be of service. Good luck with your project.


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

Thanks


Hezekiah profile image

Hezekiah 4 years ago from Japan

Very nice Tutorial there, could you do one for Android Phones too?


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

Hi Hezekiah,

For Android apps, the best data storage is SQLite if you are using a local database. Of course you can also connect to a database server either using a web service, a native driver or ODBC. I would happy to provide a tutorial on this. Stay tuned.


dh 4 years ago

Thanks for the great tutorial.

If anyone else tries this using the simulator and gets an error that says “The model used to open the store is incompatible with the one used to create the store” then the solution is to delete the app from your simulator and try again.


klanguedoc profile image

klanguedoc 4 years ago from Canada Author

Yes, if you create a core data project then initial run as is, the default data model will be created in SQLite database that is being used the storage facility. So you would need to delete the app from the Simulator and re-run the app once the data model is changed in the Core Data Editor.


nardine 4 years ago

Hi Klanguedoc,

Thanks for another very useful tutorial.

I was wondering, how would you go about automatically preloading core data with data from an already existing sqlite db with data in. The sqlite db has at least 365 rows in it so an efficient method to transfer this data would be nice.

Question 2: With an sqlite db with at least 365 rows of data (mostly string data of variable len) would using core data offer any added advantage? (e.g access speed or performing fetch requests like select queries)?

Thanks a lot! and keep up the great work.


Dan 3 years ago

Awesome tutorial mate!! Do you intend to do a short tutorial on JSON and core data interaction? that would be awesome, hope to hear from you


klanguedoc profile image

klanguedoc 3 years ago from Canada Author

Nardine,

sorry for the late reply. When you setup the core data in the appdelegate, specify your preloaded db. I haven't tried before but it should work. Core data won't give you better performance. It is using the same sqlite i/o under the hood. Core data gives you an ER and ORM and data management.

Dan,

I have been musing about it. I am always looking for inspiration for new tutotials :)

However right now I am swamped with projects. it is hard to do any writing.

    Sign in or sign up and post using a HubPages Network account.

    0 of 8192 characters used
    Post Comment

    No HTML is allowed in comments, but URLs will be hyperlinked. Comments are not for promoting your articles or other sites.


    Click to Rate This Article
    working