TweetFollow Us on Twitter

The Road to Code: Writing Even Less Code

Volume Number: 24
Issue Number: 12
Column Tag: The Road to Code

The Road to Code: Writing Even Less Code

Introduction to Core Data

by Dave Dribin

Core Data

Our topic this month is Core Data, a technology introduced in Mac OS X 10.4 by Apple to help reduce time spent writing code. Interface Builder allows you to setup view classes with out writing any custom layout code. Cocoa bindings allow you tie together the view and the model without writing any custom controller code. What's left? The model. Core Data is an attempt to allow developers to write model classes without writing any code.

Core Data was introduced in Mac OS X 10.4 and heavily enhanced in OS X 10.5. In a nutshell, Core Data provides automatic object persistence and object lifecycle management. The phrase object persistence is a fancy way of saying "saving objects to a file," similar to archiving. Core Data provides more, though. It allows you to find and filter objects and provides integration with the user interface, such as automatic undo support. It can optionally store your objects to a single-user relational database for increased performance.

It is common to think of Core Data as an object-relational mapping (ORM) tool. ORM tools automatically persist objects to a relational database. ORM tools allow you to save, find, and update objects using SQL statements. SQL is the language of relational databases, and ORM tools typically generate the SQL select, update and insert statements for you. Some popular ORM tools in the Java world are Hibernate and Enterprise Java Beans (EJB), and Active Record is the ORM tool for Ruby on Rails.

However, there is one very important difference between most ORM tools and Core Data. Most ORM tools are designed for multi-user and high-concurrency environments, such as the backend of web application. Core Data is designed with the single-user desktop application in mind. You'll see some of the ramifications of this as you delve into the architecture and use cases of Core Data. For example, Core Data does not require use of a relational database.

A Bit of History

Before digging into the details of Core Data, it is useful to understand where it came from. It turns out that Apple has it's own web-based ORM tool as part of WebObjects. WebObjects is a complete web application framework. It started life way back in the early 1990s at NeXT written in Objective-C and was later rewritten in Java. When Apple acquired NeXT, mainly for Mac OS X, it also acquired WebObjects. Today, Apple uses WebObjects for its online store and the server side components of the iTunes Music Store. It is also available for free for developers to use and has quite a strong, albeit small, following.

WebObjects includes an ORM tool called Enterprise Objects Frameworks, or EOF. It allows automatic persistence of Java model objects to a relational database. As far as ORM tools go, EOF is quite powerful and feature filled. However, since it is now only available in Java, it is not something that can be used directly by Cocoa applications.

Apple used its experience with EOF to design Core Data. It took many of the concepts of EOF and pared them down for single-user applications. There is no direct link between EOF and Core Data, just a foundation of ORM experience. Unfortunately, not all of the features of EOF were ported to Core Data, so sometimes we are left wanting.


Core Data introduces some new terminology, mainly borrowed terminology from the database world. Databases are modeled using the entity-relationship model, thus Core Data objects are also modeled using the entity-relationship model. But don't fret, most of these terms correlate to terms you already know.

In an entity-relationship model, a class is called an entity. And just classes contains instance variables, entities contain properties. There are two kinds of properties: attributes and relationships. Attributes are properties consisting of simple data types, such as strings, numbers, and dates. Relationships are properties that link together multiple entities. We won't be covering relationships in this article.

Okay, enough of the jibber jabber, let's get on to writing a Core Data application.

Core Data Version of Rectangles

We are going to convert the Rectangles application that we have built up over the last few months to a Core Data application. Using Core Data will allow us to remove almost all of our code. We can't quite get rid of all of it, but the reduction is still dramatic.

We're going to start off my creating a new project. Create a Core Data Document-based Application from the New Project window, as shown in Figure 1.

Figure 1: New Core Data project

This project looks similar to standard document-based applications, but it has an additional group in the Groups & Files list called Models, as shown in Figure 2. In that group is a file named MyDocument.xcdatamodel. This file extension is short for "Core Data data model" and represents the entity-relationship model for our application.

Figure 2: Groups and Files

We're going to dive right in by working on our data model first. We want to create a rectangle entity with width and height attributes. If you double click on the data model, you will be presented with what is known as the Core Data modeler, as shown in Figure 3. We will design our data model graphically without writing any code or text.

Figure 3: Core Data modeler

Click the + button in the Entity pane to create a new entity. Use the detail view on the right side of the window to rename the entity to Rectangle, as shown in Figure 4.

Figure 4: Rectangle entity

Next, add a new attribute by making sure the Rectangle entity is still selected and click the + button in the Property pane. Rename the attribute to width, uncheck the Optional checkbox, change the Type to Float, and set the Default Value to 0. Now repeat this process to create a height attribute. The result should look like Figure 5.

Figure 5: Height and width attributes

In the bottom half of the window, you will see a graphical representation of our entity-relationship model, as shown in Figure 6. This graphical representation is called an entity-relationship diagram or ER diagram. It is common to model relational databases using an ER diagram, again showing the database roots of Core Data.

Figure 6: Rectangle ER diagram

With that, we're done with our data model. We can now save, load, and use Rectangle entities in our application. But, we haven't written any code, yet. How can you use an entity without any code? Core Data provides built-in classes to make this easy.

Core Data Class Architecture

When you created the Rectangle entity, you'll notice that one of the fields is named Class and, by default, is set to NSManagedObject. Every instance of a Core Data entity is represented by an instance of NSManagedObject. In a way, it is similar to how NSObject is the root class of all Objective-C classes. However, you do not need to subclass NSManagedObject to use it. So how do you access the properties? Using key-value coding.

When an NSManagedObject, or managed object for short, gets instantiated, it's initialized for a particular entity. The managed object reads your data model and allows you to access the attributes using the standard KVC valueForKey: and setValue:forKey: methods. For example, say we have an instance of NSManagedObject representing our Rectangle entity. You would access the width attribute like:

    NSManagedObject * rectangle = ...;
    NSNumber * width = [rectangle valueForKey:@"width"];
    NSLog(@"Width is: %f", [width floatValue]);

But for now, we do not need to use our entity from code. We will be using Cocoa bindings to connect managed objects to the user interface, which uses KVC.

Another important class in the Core Data architecture is NSMangedObjectContext, or managed object context. You use the managed object context to find, create, and delete managed objects. Every managed object instance is owned by the managed object context that created it. The managed object context also contains unsaved changes. Thus, when the user makes their edits, these changes occur only the managed object context. To save these changes to disk, you tell the managed object context to save.

The final important class in the Core Data architecture is NSPersistentStoreCoordinator, or persistent store coordinator. A persistent store coordinator links a managed object context to a specific file on disk, called a persistent store. There are three types of persistent stores that defines the internal file format on disk: XML, binary, and SQLite. The XML persistent store is nice because you can use any text editor to examine the contents. The binary persistent store is faster and more efficient, but it is a proprietary file format. The SQLite persistent store type is the most interesting.

SQLite is a full relational database system that is self-contained and serverless. Most relational database systems, like PostgreSQL, MySQL, or Oracle, require a separate server process to run in the background. A server-based relational database requires a lot of extra setup and can be a little difficult to maintain. SQLite on the other hand is linked in as part of your application and the database is stored in a single file on disk. You access the data using standard SQL queries. SQLite cannot handle highly concurrent multi-user applications like busy web applications, but it is perfect for a single user application, like an OS X application.

When Core Data uses a SQLite persistent store, it works very much like traditional ORM tools. It generates SQL statements to create, save, and find objects in the database. Core Data does not allow you to interact with SQLite directly, though. It hides all the SQL from the programmer.

The benefit of using a SQLite persistent store type is that it is much more efficient than the XML and binary types. Only the objects that you are using get loaded into memory. Thus if the user's data contains a large amount of entities, SQLite will only load the objects the user is using, saving memory. Also, finding and filtering managed objects are more efficient since Core Data can use SQL to find the objects. Databases are designed to perform searches very efficiently.

Generally, you use the XML persistent store type during the early stages of development, because the file can be read with a text editor. However, SQLite is often the best case for a released application since it is more efficient. There are some subtle differences between the persistent store types, so if you do change persistent store types, be sure to thoroughly test after the changes. Also, if you change the type, your application will not be able to load previously saved files.

I admit that the Core Data architecture is somewhat complex. However, if you are writing a document-based application, your life is simplified. Apple provides an NSDocument subclass for document-based applications that use Core Data called NSPersistentDocument. The NSPersistentDocument takes care of setting up the persistent store coordinator and managed object context for you. When you save your document, it saves the context to the user's file. Since we chose a Core Data Document-based Application, our MyDocument class is automatically a NSPersistentDocument.

Configuring the Document Type

Let's now setup the document type for our application, so we can save and open files. Double-click on the Rectangles target to open the Info window for this target. You'll notice there are three document types already present, one for each of the different persistent store types. We'll use SQL type, so delete the other two. Change the Name to Rectangles Document and the extension to rectanglescd. We already used the rectangles extension in our previous, non-Core Data application, so we want to choose a different one to avoid a conflict.

Also change the Identifier to something unique. All of these changes are summarized in Figure 7.

Figure 7: Document types

Laying out the User Interface

We're now going to switch to Interface Builder to layout the interface and setup our Cocoa bindings. Remove the initial text label, and add a table view. Rename the columns to Width and Height. Drag number formatters on each of the columns and set their Style to Decimal. Now add two buttons underneath the table, one named Add the other named Remove. Setup the autosizing appropriately. The final result should look like Figure 8.

Figure 8: Initial window layout

Next, we're going to create an array controller for our Cocoa bindings. Drag an array controller from the Library to our xib document window, and rename it to Rectangles, as shown in Figure 9.

Figure 9: Array controller

Now setup the array controller's attributes to match Figure 10. You need to set the Mode to Entity, set the Entity Name to Rectangle, and check the Prepares Content checkbox. This puts the array controller into Core Data mode and will hold instances of NSManagedObject of the given entity name.

Figure 10: Array controller attributes

Our array controller needs a managed object context to fetch and edit managed objects. Remember that NSPersistentDocument sets up a context for each document. The File's Owner for the MyDocument.xib is our MyDocument subclass of NSPersistenDocument. We can bind the array controller's Managed Object Context to the managedObjectContext of File's Owner, as shown in Figure 11.

Figure 11: Array controller bindings

With our array controller in place, we can now bind the Width and Height columns. Just as we did for our non-Core Data application, bind the Width column to the Rectangles array controller. Set the Controller Key to arrangedObjects and the Model Key Path to width, as shown in Figure 12. Make similar bindings for the Height column, except using height as the Model Key Path.

Figure 12: Width column bindings

Finally, hookup the Add button to the Rectangles array controller's add: action and the Remove button to the remove: action. Bind the Add button's Enabled binding to the canAdd Controller Key and bind the Remove button's Enabled binding to the canRemove Controller Key.

At this point, we have a fully functional application. You should be able to add and remove rectangles from the table using the buttons, and you should be able to save and open documents. Furthermore, you will notice that you get dirty document and undo support. Now I'd like to remind you again that we haven't written any code. This is the promise of Core Data.

Of course our application is missing a few things from our non-Core Data version. First, the default width for new rectangles was 15 and the default height was 10. In our non-Core Data version, we created our own subclass of array controller and overrode the newObject method. We can certainly do that, but for now, I'm going to just change the default values in the data model, to keep with the "no code" theme.

The other major part missing is the area and perimeter table columns. Unfortunately, we are going to have to create some code to get these working. Because these are computed properties, we cannot add them in the data model. We're going to have to create a subclass of NSManagedObject for our Rectangle entity. Fortunately, Xcode can give us a head start. Make sure that your data model is selected in the Groups & Files list and click on File > New File to create a new file. Click on Managed Object Class in the New File window, as shown in Figure 13.

Figure 13: Generate managed object

Click Next as the Location and Target defaults should be correct. In the final screen, make sure that the Rectangles entity is selected as shown in Figure 14 and click Finish. This will create Rectangle.h and Rectangle.m files. You may want to move them in the Models group along with your data model file so you remember that they are managed objects.

Figure 14: Generate Rectangle class

If you look at the header, you'll see just a couple of @property declarations. There are no instance variables. Remember that the values are actually stored by the NSMangedObject superclass using KVC, so we don't need any instance variables in our subclass. These properties provide convenient, type-safe access to the entity's properties. The implementation file uses the @dynamic property keyword instead of the @synthesize. This is again because there are no instance variables.

Note that the width and height are of type NSNumber, even though we set them as Float in the data model. Core Data only deals with objects. If you want to get the actual float value, you need to use the floatValue method of NSNumber. Conversely, if you want to set the float value, you need wrap a float in an NSNumber:

    // Get the width as a float
    float width = [rectangle.width floatValue];
    // Set the width from a float
    rectangle.width = [NSNumber numberWithFloat:30.0];

Now that we have a real class, we can add our area and perimeter properties. Just as in our non-Core Data application, they are read-only. Listing 1 shows the full header with the property declarations:

Listing 1: Rectangle.h

#import <CoreData/CoreData.h>
@interface Rectangle :  NSManagedObject  
@property (retain) NSNumber * width;
@property (retain) NSNumber * height;
@property (readonly) float area;
@property (readonly) float perimeter;

I used float here because it is easier to deal with primitive types when doing math. The implementation of these properties is similar to our non-Core Data application. We do have to convert the width and height to floats so we can perform math on them, though. The key-value observing methods are the same, however. Listing 2 shows the full implementation file.

Listing 2: Rectangle.m

#import "Rectangle.h"
@implementation Rectangle 
@dynamic width;
@dynamic height;
- (float)area
    return ([self.width floatValue] *
            [self.height floatValue]);
+ (NSSet *)keyPathsForValuesAffectingArea
    return [NSSet setWithObjects:@"width", @"height", nil];
- (float)perimeter
    return ((2*[self.width floatValue]) +
             (2*[self.height floatValue]));
+ (NSSet *)keyPathsForValuesAffectingPerimeter
    return [NSSet setWithObjects:@"width", @"height", nil];

And that's all the code we need. Now, we just need to add the remaining elements to the user interface.

Creating the Final User Interface

Switch to Interface Builder to complete the changes. Add two more columns to the table view and label them Area and Perimeter, respectively. Make sure they are marked as uneditable and add Decimal number formatters to both. Bind them to arrangedObjects.area and arrangedObjects.perimeter, respectively, of the Rectangles array controller. Figure 15 shows the bindings for the Area column.

Figure 15: Area column bindings

Add four labels at the bottom left side of the table for the Total Area: and Total Perimeter: fields. Two will be used for static text and two will be used for the actual values. For the two used for the values, add Decimal number formatters. The final window layout should look like Figure 16.

Figure 16: Final window layout

We are now going to setup the bindings using collection operators, just like we did in the non-Core Data application. Bind the total area value label to the Rectangles array controller. Set Controller Key to arrangedObjects and the Model Key Path to @sum.area. The result should look like Figure 17. Next, bind the total perimeter value field to the @sum.perimeter Model Key Path.

Figure 17: Total area bindings

We are now finished with our changes. You should be able to run the application and have the area and perimeter user interface elements work appropriately. Our application is nearly identical to our non-Core Data application, and all we had to do was write four methods for the area and perimeter. And this includes support for undo! Not to shabby.

Caveat Emptor

There is one subtle difference from our non-Core Data application. In our previous application, we store an array of rectangles in the document. This means that as we added rectangles, their order is preserved. Core Data uses sets, instead of arrays, which means they are unordered. But surely they have to show up in some order in the table. Unordered just means the order is not consistent. The list of rectangles may show up in a different order every time you load the file. Since the user can sort the table by clicking on one of the table columns, the easy way to fix the problem is to always sort the table by a column, by default. To truly remember the order of the items as they were entered is a very difficult Core Data problem, though. And even though setting up default column sorting is significantly easier, it is still beyond the scope of this article. For now, we'll just have to deal with that limitation.

Also, this article just scratches the tip of the Core Data iceberg. There are many more advanced topics, such a relationship properties, threading techniques, and migration between different versions of your model. Apple's documentation has a lot of information on these topics.


Even though Core Data is a complicated subject with some limitations, it is still a hugely valuable asset to Mac OS X development. It can save you from writing a lot of your own model code, just as Cocoa bindings can save you from writing a lot of controller code. It won't eliminate code completely, but I urge you to at least investigate Core Data for your future applications.

Dave Dribin has been writing professional software for over eleven years. After five years programming embedded C in the telecom industry and a brief stint riding the Internet bubble, he decided to venture out on his own. Since 2001, he has been providing independent consulting services, and in 2006, he founded Bit Maki, Inc. Find out more at and


Community Search:
MacTech Search:

Software Updates via MacUpdate

Gopogo guide - How to bounce like the be...
Nitrome just launched a new game and, as to be expected, it's a lot of addictive fun. It's called Gopogo, and it challenges you to hoparound a bunch of platforms, avoiding enemies and picking up shiny stuff. It's not easy though - just like the... | Read more »
Sago Mini Superhero (Education)
Sago Mini Superhero 1.0 Device: iOS Universal Category: Education Price: $2.99, Version: 1.0 (iTunes) Description: KAPOW! Jack the rabbit bursts into the sky as the Sago Mini Superhero! Fly with Jack as he lifts impossible weights,... | Read more »
Star Wars: Galaxy of Heroes guide - How...
Star Wars: Galaxy of Heroes is all about collecting heroes, powering them up, and using them together to defeat your foes. It's pretty straightforward stuff for the most part, but increasing your characters' stats can be a bit confusing because it... | Read more »
The best cooking apps (just in time for...
It’s that time of year again, where you’ll be gathering around the dinner table with your family and a huge feast in front of you. [Read more] | Read more »
Square Rave guide - How to grab those te...
Square Rave is an awesome little music-oriented puzzle game that smacks of games like Lumines, but with its own unique sense of gameplay. To help wrap your head around the game, keep the following tips and tricks in mind. [Read more] | Read more »
Snowboard Party 2 (Games)
Snowboard Party 2 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Crowned the best snowboarding game available on the market, Snowboard Party is back to fulfill all your adrenaline needs in... | Read more »
One Button Travel (Games)
One Button Travel 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: “To cut a long story short, If you like interactive fiction, just go buy this one.” - “Oozes the polish that... | Read more »
Light Apprentice Volume 1 (Games)
Light Apprentice Volume 1 1.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: Light Apprentice Volume 1 includes Chapters 1 to 4, all gathered in a new exclusive game. When life in the world of... | Read more »
The best games like Animal Crossing on m...
Animal Crossing amiibo Festival is out right now for the Wii U, reminding us of just how much fun that world can be. Or at least to go back and check in on our villages once in a while. [Read more] | Read more »
Between 2 Taps - Tap for Tap interview M...
Hello, and welcome back to Between 2 Taps, Tap for Tap’s Indie Dev interview series. [Read more] | Read more »

Price Scanner via

Black Friday deals on the Apple Watch and App...
Apple resellers are offering discounts and bundles with the purchase of an Apple Watch this Black Friday weekend. Below is a roundup of the deals being offered by authorized Watch resellers: Apple... Read more
Early Black Friday sale at B&H Photo, up...
B&H Photo has all new Macs on sale for up to $500 off MSRP as part of their early Black Friday sale including free shipping plus NY sales tax only: - 15″ 2.2GHz Retina MacBook Pro: $1699 $300 off... Read more
NewerTech/OWC/MacSales Black Friday Deals 201... • Free Shipping available on nearly EVERYTHING on orders $35.00 & up within USA + • International Delivery Specials from $2.99+ Special Purolator... Read more
Walmart Black Friday deals: $100 off select i...
Walmart has released their Black Friday deals for 2015, now available online. Choose free shipping or free local store pickup (if available): - 16GB iPad Air 2: $399, $100 off MSRP - 16GB iPad Air: $... Read more
Photo Cleaner 1.0 Reclaims iPhone Storage Spa...
Seoul, Korea based mix1009 has announced the release and immediate availability of Photo Cleaner 1.0, their handy iPhone app that deletes the video portion of Live Photos, in order to reclaim space... Read more
Black Friday and Holiday sales on our price t...
Scan our Mac Price Trackers for the latest Black Friday and Holiday season information on sales, bundles, and availability on systems from Apple’s authorized internet/catalog resellers. We update the... Read more
Best Buy Black Friday deals: Up to $200 off M...
Best Buy has posted their Black Friday sale prices for 2015. Save on MacBook Pros, MacBooks, MacBook Airs, iMacs, iPads, and Apple Watches. Choose free shipping or free local store pickup (if... Read more
Save $30-$40 on new Apple TVs after rebate
Adorama has new Apple TVs on sale for up to $40 off MSRP after mail-in rebate, good through December 15th. Shipping is free, and Adorama charges NY & NJ sales tax only: - 32GB Apple TV: $119.99... Read more
13-Inch Haswell MacBook Air At Two Years – Th...
The 13-inch mid-2013 “Haswell” MacBook Air I ordered in Apple’s November 2013 Black Friday sale was my first new Mac in four and a half years — the longest interval I’ve gone between system upgrades... Read more
Target Black Friday Early Access deals: $100...
Target is offering early access to their Black Friday deals on Apple products on their online store for today, the 25th, only. Choose free shipping or free local store pickup (if available): - Apple... Read more

Jobs Board

*Apple* Enterprise / Government Professional...
# Apple Enterprise / Gove ment Professional Services Engineer Job Number: 42292976 Reston, Virginia, United States Posted: Aug. 18, 2015 Weekly Hours: 40.00 **Job Read more
iOS Wallet & *Apple* Pay Engineer - App...
# iOS Wallet & Apple Pay Engineer Job Number: 40586801 Santa Clara Valley, Califo ia, United States Posted: Nov. 16, 2015 Weekly Hours: 40.00 **Job Summary** The iOS Read more
Software Engineer, *Apple* Watch - Clock Fa...
# Software Engineer, Apple Watch - Clock Face Team Job Number: 44368761 Santa Clara Valley, Califo ia, United States Posted: Nov. 14, 2015 Weekly Hours: 40.00 **Job Read more
Administrative Assistant, *Apple* Online St...
# Administrative Assistant, Apple Online Store Job Number: 43992352 Santa Clara Valley, Califo ia, United States Posted: Nov. 9, 2015 Weekly Hours: 40.00 **Job Summary** Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.