Core Data

Core Data is a framework that allows creating relational data base. How to create a project using Core Data is shown on example which stores names. Create new project, choose “Window-based Application” and “Use Core Data for storage” (image 1).

In “Resources” you will find xcdatamodel file in which you can see entities, attributes and relations between them. Entity (i.e. Managed Object) is: “Name”, attributes are: “First_name” and “Last_name” (image 2).

Image 2.

Next step is to create NSManagedObject class. Choose entity, then File > New File and “Managed Object Class”.

Name.h


#import 


@interface Name :  NSManagedObject  
{
}

@property (nonatomic, retain) NSString * Last_name;
@property (nonatomic, retain) NSString * First_name;

@end

Name.m


#import "Name.h"


@implementation Name 

@dynamic Last_name;
@dynamic First_name;

@end

Class “NameViewControler” will be used for adding names to data base and for displaying names from data base. In header you have to define pointer on object of NSManagedObjectContext class and array namesArray.

NameViewControler.h


#import 
#import "Name.h"

@interface NameViewController : UIViewController 
{
	NSManagedObjectContext *managedObjectContext;  
	NSMutableArray *namesArray;   
	IBOutlet UITableView *nameTable;
	IBOutlet UITextField *textFieldFirstName, *textFieldLastName;
}

@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;  
@property (nonatomic, retain) NSMutableArray *namesArray;   
   
- (void)fetchNames;  
- (IBAction)addName:(id)sender;   

@end

NSManagedObjectContext manages entities. All requests between your application and data base go through NSManagedObjectContext (image 3).

Image 3.

Name will be aded to data base with selector addName:. Object name represents one row in table. Data from data base are add to array namesArray with selector fetchNames. To create request create NSFetchRequest object and set its entity. Entity is set with name and context. For sorting data use NSSortDescription.

NameViewControler.m


@implementation NameViewController

- (void)viewDidLoad 
{
	[super viewDidLoad];
	[self fetchNames];   
}


- (IBAction)addName:(id)sender 
{   
	[textFieldFirstName resignFirstResponder];
   	[textFieldLastName resignFirstResponder];

	Name *name = (Name *)[NSEntityDescription insertNewObjectForEntityForName:@"Name" inManagedObjectContext:managedObjectContext];  
	[name setFirst_name:textFieldFirstName.text];   
   	[name setLast_name:textFieldLastName.text];   
	
	NSError *error;  
	
	if(![managedObjectContext save:&error])
	{  
		//try again
	}  
	
	[namesArray insertObject:name atIndex:0];
	
	[nameTable reloadData];
	
	textFieldFirstName.text = @"";   
   	textFieldLastName.text = @"";   
}  


- (void)fetchNames 
{   
     NSEntityDescription *entity = [NSEntityDescription entityForName:@"Name" inManagedObjectContext:managedObjectContext];   

     NSFetchRequest *request = [[NSFetchRequest alloc] init];  
     [request setEntity:entity];   
   
     NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Last_name" ascending:NO];  
     NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];  
     [request setSortDescriptors:sortDescriptors];  
     [sortDescriptor release];   
   
     NSError *error;  
     NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];   
   
     if (!mutableFetchResults) 
	{  
         // Handle the error.  
     }   
   
     [self setNamesArray: mutableFetchResults];  
     [mutableFetchResults release];  
     [request release];  
}   


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{
    return 1;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
	static NSString *CellIdentifier = @"Cell";
	
	UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
	if (cell == nil)
		cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
	
	Name *name = [namesArray objectAtIndex: [indexPath row]];
	Name *previousName = nil;
	if ([namesArray count] > ([indexPath row] + 1))
		previousName = [namesArray objectAtIndex: ([indexPath row] + 1)];

	[cell.textLabel setText:[NSString stringWithFormat:@"%@, %@", [name Last_name], [name First_name]]];

	return cell;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{
    return [namesArray count];
}


- (void)textFieldDidBeginEditing:(UITextField *)textField
{
	if ( textField == textFieldFirstName ) [textField setReturnKeyType:UIReturnKeyNext];
	else if ( textField == textFieldLastName ) [textField setReturnKeyType:UIReturnKeyDone];
}


- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
	if ( textField == textFieldFirstName) 
	{
		[textFieldLastName becomeFirstResponder];
		return NO;
	}
	else
	{
		[textField resignFirstResponder];
		return YES;
	}
}


@synthesize managedObjectContext, namesArray;   

- (void)dealloc 
{
	[managedObjectContext release];
	[namesArray release];
    [super dealloc];
}


@end