iPhone Core Data Tutorial Part 1
How to use core data on the iphone with one entity
If you need to insert data into your iPhone application, this tutorial will be for you. Before you start this tutorial, you need to have the latest version of Xcode.
To start, open up Xcode and press Shift - ⌘ - N. Under iPhone OS in the left pane, select Application, Navigation-based application. Check the Use Core Data for Storage option, click Choose..., and name the project CoreDataTutorial.
For better organization, highlight the CoreDataTutorialAppDelegate.m, press the action button - Add - New Group. Name it Data Model. Now double click your Data Model group and press ⌘ - N. Select Resource and double click on Data Model. Click next and name it recipes.xcdatamodel. Open up recipes.xcdatamodel and you will notice a new window with four different panes. The one on the left is for editing entities, the middle one is for editing attributes within those entities, the far-most one is for editing attribute or entity properties, and the one on the bottom is for entity mapping which will learn how to use later on.
In the left pane, click on the plus button at the bottom and name the entity Recipes. Make sure the Recipes entity is highlighted, click on the plus button in middle pane, and select add attribute. Name this attribute recipeName and add another attribute named cookingTime. In the middle pane under the tab Type or Destination, click on the up and down arrows and select String for both attributes. A type for an attribute means that what kind of data the attribute will hold. For example, if the attribute is a string, it will hold a phrase of text. If it is an Int 16, it will hold a number. Save recipes.xcdatamodel and close the window.
In the left pane of your project window, select recipes.xcdatamodel and press ⌘ - N. Select Coca Touch Class and you will notice that a new class has appeared named NSManagedObjectClass. This will create a .h and a .m file for our entity. Double click NSManagedObjectClass, click next, check the Recipes entity, and click Finish.
In case that the NSManagedObjectClass does not appear (I have had times when it doesn't) click cancel and make sure that the Recipes entity in your project's lower window pane is not highlighted. Then highlight the recipes.xcdatamodel file in the left window pane and press ⌘ - N. If the NSManagedObjectClass does not show up after trying this, highlight recipes.xcdatamodel and create a new NSObject class. Name it Recipes.h. Open up Recipes.h and type in the following code:
#import
@interface Recipes : NSManagedObject
{
}
@property (nonatomic, retain) NSString * recipeName;
@property (nonatomic, retain) NSString * cookingTime;
@end
In the .m file, type in:
#import "Recipes.h"
@implementation Recipes
@dynamic recipeName;
@dynamic cookingTime;
@end
Now lets create some classes. Highlight the CoreDataTutorialAppDelegate.m and press ⌘ - N. Create a UIViewController named AddRecipeViewController and a UITableViewController named RecipeDetailViewController. Open up AddRecipeViewController.h and type in:
#import
@class Recipes;
@interface AddRecipeViewController : UIViewController {
Recipes *recipes;
UITextField *textFieldOne;
UITextField *textFieldTwo;
}
@property (nonatomic, retain) Recipes *recipes;
@property (nonatomic, retain) IBOutlet UITextField *textFieldOne;
@property (nonatomic, retain) IBOutlet UITextField *textFieldTwo;
@end
We need to import the Recipes class so we can editing the attributes that are in the Recipes entity. In the .m file, type in:
#import "AddRecipeViewController.h"
#import "Recipes.h"
@implementation AddRecipeViewController
@synthesize recipes, textFieldOne, textFieldTwo;
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Add Recipe";
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel)];
self.navigationItem.leftBarButtonItem = cancelButton;
[cancelButton release];
UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] initWithTitle:@"Save" style:UIBarButtonItemStyleDone target:self action:@selector(save)];
self.navigationItem.rightBarButtonItem = saveButton;
[saveButton release];
}
- (void)cancel {
[recipes.managedObjectContext deleteObject:recipes];
NSError *error = nil;
if (![recipes.managedObjectContext save:&error;]) {
// Handle error
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
[self dismissModalViewControllerAnimated:YES];
}
- (void)save {
recipes.recipeName = textFieldOne.text;
recipes.cookingTime = textFieldTwo.text;
NSError *error = nil;
if (![recipes.managedObjectContext save:&error;]) {
// Handle error
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
[self dismissModalViewControllerAnimated:YES];
}
Now you are probably wondering what this segment of code means:
NSError *error = nil;
if (![recipes.managedObjectContext save:&error;]) {
// Handle error
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
This is to save your work and insert it into your entity. Open up AddRecipeViewController.xib and create a view with two UITextFields parallel to each other and UILabels left of the textFields. Next to the first UITextField, name the label Name: and next to the second UITextField, name the label Cooking Time:. Now connect the two UITextFields to the File's Owner. Make the first UITextField connected to textFieldOne and the second one textFieldTwo. Control click and drag from both of the UITextFields to the File's Owner and select Delegate. Before you save, make sure the File's Owners view is setting or else when you click on the add button in the RootViewController, your program will crash. Save it and quit out of Interface builder.
Double click on RecipeDetailViewController.h and enter this code:
#import
@class Recipes;
@interface RecipeDetailViewController : UITableViewController {
Recipes *recipes;
}
@property (nonatomic, retain) Recipes *recipes;
@end
In the .m file, enter:
#import "RecipeDetailViewController.h"
#import "Recipes.h"
@implementation RecipeDetailViewController
@synthesize recipes;
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellIdentifier] autorelease];
}
switch (indexPath.row) {
case 0:
cell.textLabel.text = @"Name";
cell.detailTextLabel.text = recipes.recipeName;
break;
case 1:
cell.textLabel.text = @"Cooking Time";
cell.detailTextLabel.text = recipes.cookingTime;
break;
default:
break;
}
return cell;
}
- (void)dealloc {Where it says
[recipes release];
[super dealloc];
}
@end
Save both files and open the RootViewController.m and type in the following code:
#import "RootViewController.h"
#import "AddRecipeViewController.h"
#import "Recipes.h"
#import "RecipeDetailViewController.h"
@implementation RootViewController
@synthesize fetchedResultsController, managedObjectContext;
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Recipes";
self.navigationItem.leftBarButtonItem = self.editButtonItem;
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addRecipe)];
self.navigationItem.rightBarButtonItem = addButton;
[addButton release];
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error;]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView reloadData];
}
#pragma mark -
#pra[removed][removed]gma mark Add a new object
- (void)addRecipe {
AddRecipeViewController *addRecipeView = [[AddRecipeViewController alloc] initWithNibName:@"AddRecipeViewController" bundle:[NSBundle mainBundle]];
Recipes *recipes = (Recipes *)[NSEntityDescription insertNewObjectForEntityForName:@"Recipes" inManagedObjectContext:self.managedObjectContext];
addRecipeView.recipes = recipes;
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController: addRecipeView];
[self.navigationController presentModalViewController:navController animated:YES];
[addRecipeView release];
}
#pragma mark -
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [[fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [[managedObject valueForKey:@"recipeName"] description];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
RecipeDetailViewController *recipeDetailView = [[RecipeDetailViewController alloc] initWithStyle:UITableViewStyleGrouped];
Recipes *recipes = (Recipes *)[fetchedResultsController objectAtIndexPath:indexPath];
recipeDetailView.recipes = recipes;
[self.navigationController pushViewController:recipeDetailView animated:YES];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSManagedObjectContext *context = [fetchedResultsController managedObjectContext];
[context deleteObject:[fetchedResultsController objectAtIndexPath:indexPath]];
NSError *error = nil;
if (![context save:&error;]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
#pragma mark -
#pragma mark Fetched results controller
- (NSFetchedResultsController *)fetchedResultsController {
if (fetchedResultsController != nil) {
return fetchedResultsController;
}
/*
Set up the fetched results controller.
*/
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Recipes" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
// Set the batch size to a suitable number.
[fetchRequest setFetchBatchSize:20];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"recipeName" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
return fetchedResultsController;
}
// NSFetchedResultsControllerDelegate method to notify the delegate that all section and object changes have been processed.
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
// In the simplest, most efficient, case, reload the table view.
[self.tableView reloadData];
}
- (void)dealloc {
[fetchedResultsController release];
[managedObjectContext release];
[super dealloc];
}
@end
Where it says - (void)addRecipe, we are inserting a new entity into our database with this line of code:
Recipes *recipes = (Recipes *)[NSEntityDescription insertNewObjectForEntityForName:@"Recipes"inManagedObjectContext:self.managedObjectContext];
when we say addRecipeView.recipes = recipes; we are passing on the recipes entity to edit or view.
Now Click build and go and play around with it. Part 2 will be about how to use to entities and inset images into our database. The source code can be found here: http://sites.google.com/site/iprogramiphones/bukisatutorials/coredatatutorialpart1.
Check out Part 2: http://www.bukisa.com/articles/188059_iphone-core-data-tutorial-part-2.
Thanks for reading!
What kind of tutorial would you like next? Post your answer as a comment on this page.
Problems with coding? Email me @ edwardhinsa@gmail.com.
Have a dog and an iPod Touch and an iPhone? http://itunes.apple.com/WebObjects/MZStore.woa/wa/browserRedirect?url=itms://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=332655618&mt=8
-
iPhone Core Data Tutorial Part 2
| By eh9212 | in Programming
How to use relationships between entities, edit attributes, and insert images into a database....
-
Armored Core 4 Achievement List Xbox 360
| By geske1221 | in Computer & Video Games
Here is a list of achievements with descriptions for Armored Core 4 on the Xbox 360 gaming console....
-
About Data Entry Useful Tips!!
| By babsurvey | in Motivational
Data entry or type-at-home programs can be very profitable for anyone with the required level of skills and motivat...
-
Data Centre Solutions UK!
| By Arvind0 | in Computers
Data Centre Solutions form an integral part of the unique IT solution and Services. Consider your guide to find out...
-
XA Transaction - Solution for Transaction More Than One Database | By H4d1 | in Programming
Have you ever think that it's too difficult for making database transaction in two different places (or databases) ...
-
Javascript functions for : trim, right trim, left trim, no Apostrophe, is Empty , is Digit , VarChar To Number , is integer , check Is Zero , Get Que | By xxris | in Programming
Javascript functions for : trim, right trim, left trim, no Apostrophe, is Empty , is Digit , VarChar To Number , i...
-
How to access and use a Window's command line | By MaxwellPayne | in Programming
Learn about the Window's command line in DOS and how to use it....
-
How to Learn to Program Your Computer | By dsj8760 | in Programming
This article is about learning to program a computer. It is a general article giving tips on how to learn about pro...
-
Jailbroken iPhones get RickRolled | By explorer | in Programming
First iPhone worm, attacks via SSH and does the classic rick roll gag on the user....
-
iPhone Core Data Tutorial Part 2 | By eh9212 | in Programming
How to use relationships between entities, edit attributes, and insert images into a database....
-
iPhone Modal Tab Bar Controller with Navigation Controller | By eh9212 | in Programming
How present a modal tab bar controller with navigation controllers...
-
iPhone UISegmentedControl Tutorial Part 1 | By eh9212 | in Programming
How to change text in a UILabel using a UISegmentedControl...








No comments yet.