If you are used to relational databases and the jargon associated with them the learning curve for the how a small database on the iPhone is setup can be confusing.

Let's walk through creating a simple database and using the object created by it. We'll take requirements from iPhone Boot Camp training that was provided by Jack Cox.

As you can see from the diagram we need three tables; ZipCodeData and LocationData with a CrossReference table which will allow us to quickly get a certain locations (or zip codes) entire geographical data. If we have the zip code we can get the City from LocationData; you get the picture. Coming from a world of typical enterprise rational databases this is pretty easy. You are looking at three entities and two relationships. There is one zip code to one location and there are many of these tuples in CrossReference.

After browsing through the Apple online documentation it becomes apparent that we want to create a Core Data data model for this simple example, which becomes a .xcdatamodelId file. Inside the Xcode 4 editor you have a screen (which is populated in my example) below:

It's all point, click and type. You add the entity attributes and it's relationships and something called Fetched Properties which are beyond the scope of this blog article. The O in relationship means optional and the M means to-many relationship. From this all we know is that the relationship named "Locations" says ZipCodeData has a to-many relationship on LocationData (destination) and the relationship is inverse, so it's not one-to-many, but many-to-many. The Apple tutorial may mention SQLLite being used, someone coming from a SQL Server or Oracle world would latch onto that when trying to understand Apple's Core Data API.

Apple uses the same kind of typical relational jargon to help us understand their Core Data API (entities, relationships, tables). Unforuntately when someone says tables and entities to me I'm already at the DB implementation layer. I'm thinking SQL Server/Oracle/etc primary keys etc. Apple's documentation is designed to reach an atypical relational DB user but they are actually trying to convey a much higher level idea which makes the learning curve a little steeper.

Core Data does not have SQLLite entities or tables or primary keys. In fact ; "The SQLite store is but one of four persistence options and the data model itself is wholly independent of which persistence option you choose i.e. the same model will work with all types of stores." (ref. http://stackoverflow.com/questions/6525321/xcode4-core-data-relationships). Core Data should be looked at as a high level way of creating object graphs. You simply define the relationships and "entities" at a high level and it will fit that definition into whatever DB type system you are using.

Hopefully this rather large stumbling block (was for me) will help you get started using Core Data much quicker.

Then it's just down to coding! Here's some samples to get you started.

After you've created the object graph in Xcode you can do things like the below:

LocationData *locationData = [NSEntityDescription insertNewObjectForEntityForName:@"LocationData" inManagedObjectContext:context];
 
ZipCodeData *zipCodeData = [NSEntityDescription insertNewObjectForEntityForName:@"ZipCodeData" inManagedObjectContext:context];
 
CrossReference *crossReference = [NSEntityDescription insertNewObjectForEntityForName:@"CrossReference" inManagedObjectContext:context];
 
 crossReference.Locations = locationData;
 
 crossReference.ZipCodes = zipCodeData;

If you are using a ViewController then you just need to declare a NSFetchedResultsController.

In the ViewController.h

 @property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController; 
 @property (nonatomic, retain) NSManagedObjectContext *managedObjectContext; 

In ViewController.m

 @synthesize fetchedResultsController=__fetchedResultsController;

Like so in your viewDidLoad:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"CrossReference" inManagedObjectContext:context];
 
[fetchRequest setEntity:entity];
 
 
 
 //You will use this to get information back out of your object map.
 
 
 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 
{
 
 NSInteger numberOfRows = 0;
 
 
 
 id sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
 
 return [sectionInfo numberOfObjects];
 
}

To display cell information:

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
 
{
 
 CrossReference *crossReference = [fetchedResultsController objectAtIndexPath:indexPath];
 
 cell.textLabel.text = crossReference.Locations.City;
 
 
 
 //zip code, city, state, zip
 
 NSString* cellContent = [[NSString alloc] initWithFormat:@"City: %@\nState: %@\nZip Code: %@", crossReference.Locations.City, crossReference.Locations.State, crossReference.ZipCodes.ZipCode]; 
 
 
 
 cell.textLabel.text = cellContent;
 
 
 
 [cellContent release];
 
 
 
 cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
 
 cell.textLabel.numberOfLines = 3; //0 tells code to use as many lines as needed.
 
 cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:12.0];
 
 cell.textLabel.adjustsFontSizeToFitWidth =true;
 
}