Core Data on iOS 5 Tutorial: How To Preload and Import Existing Data

Adam Burkepile
Failed Banks Preloaded Data with Core Data

Failed Banks Preloaded Data with Core Data

Note from Ray: iOS Tutorial Team member Adam Burkepile has kindly updated the Core Data series to iOS 5 – I’ll post an announcement about it in a bit.

This tutorial was completely rewritten in order to show a more elegant way of preloading data by making a Mac command line app that reuses your iPhone app’s Core Data model.

I wanted to repost this specially so everyone is aware of the update/rewrite. Enjoy! :]

This is a blog post by iOS Tutorial Team member Adam Burkepile, a full-time Software Consultant and independent iOS developer. Check out his latest app Pocket No Agenda, or follow him on Twitter.

This is the second part of a three-part series to help get you up to speed with the basics of Core Data quickly.

In the first part of the series, we created a visual data model for our objects, ran a quick and dirty test to make sure it works, and hooked it up to a table view so we could see a list of our objects.

In this part of the series, we’re going to discuss how to import or preload existing data into Core Data so that we have some good default data when our app starts up.

Note that there was an earlier version of this tutorial that showed you a hackish way to preload data by directly manipulating the SQLite database. The method shown in this tutorial is much preferred as it’s more elegant and less likely to break as things change with Core Data in the future.

In the final part of the series, we’re going to discuss how we can optimize our app by using NSFetchedResultsController, to reduce memory overhead and improve response time.

Before we begin, make sure you have the project where we left it off in part 1. If you need a fresh copy, you can download it here.

Preloading / Importing Existing Data

So how do we preload data into a Core Data store, anyway? Well, there are two popular solutions to this problem:

  1. Fill in Core Data on startup from external source. For this the app can start up, notice that the database hasn’t been imported yet, and start reading in data from an external source (such as an SQLite database or XML file) and then start inserting the data into Core Data.
  2. Provide pre-filled in SQLite database. For this we’ll let Core Data create the database structure for us based on the model, and then we populate the database with a utility app. The utility app could be a Mac or iPhone app that uses Core Data to populate the database via Core Data APIs, or some kind of program that fills in the SQLite database directly. Once the database is populated, just include it with the app and make the app use it as the default database if no database already exists.

In this tutorial we are going to go with option #2, and show you how you can make a simple utility app to create a preloaded Core Data database you can use in your app.

Getting Started

The basis for the method we are going to use is that Core Data on iOS is the same Core Data on OS X, and they can both use the same models and classes.

This means we can write a simple console application on OS X to import data from a data source, stick it into a Core Data data store, and move that data store over to our iOS project. Isn’t that great?!

Let’s try this out and make a Mac command line app to preload our data. Open up Xcode and create a new project, and choose the Mac OSX\Application\Command Line Tool template.

Enter “CoreDataTutorial2” as the name fo the project, change the type to “Core Data” and make sure “Use Automatic Reference Counting” is on.

Finish creating the project, then select “CoreDataTutorial2.xcdatamodeld” and delete it. Select “Move to Trash” when it asks.

Next go into the directory for tutorial 1 and find the following files:

  • FailedBankCD.xcdatamodeld
  • FailedBankInfo.h
  • FailedBankInfo.m
  • FailedBankDetails.h
  • FailedBankDetails.m

Copy those files into the directory for this project and then drag them into Xcode.

Make sure the “Copy items into destination group’s folder (if needed)” is NOT checked but be sure to check the “Add to targets” checkbox for “CoreDataTutorial2”.

Select the main.m. You’ll notice that because we selected this as a Core Data type application, we get the same boilerplate Core Data methods we saw in tutorial 1. What we’re gonna do now is make some changes to use our model classes from the iOS project and generate the Core Data entities.

In the managedObjectModel() method replace

NSString *path = [[[NSProcessInfo processInfo] arguments] objectAtIndex:0];
path = [path stringByDeletingPathExtension];


NSString *path = @"FailedBankCD";

This is pointing the application to the FailedBankCD.xdatamodeld we added instead of the CoreDataTutorial2.xdatamodeld we deleted in the beginning.

Compile and run, and verify that you have no errors.

If you built and ran it previously, you will get the model-mismatch error we discussed in tutorial 1. To delete the sqlite db, hold option(alt) and go to the menu and select “Products” and “Clean Build Folder…”.

If you see an error like this:

NSInvalidArgumentException', reason: 'Cannot create an NSPersistentStoreCoordinator 
with a nil model'

This is because the code is looking for a ‘momd’ file (the file for a versioned Core Data Model), but if your model isn’t versioned it will be saved as plain old ‘mom’. As this article explains, the quickest fix is to replace the line in managedObjectModel() like so:

 NSURL *modelURL = [NSURL fileURLWithPath:[path stringByAppendingPathExtension:@"mom"]];

Now it should compile and run fine (with no output yet).

Importing the Data

Now on to the fun part – preloading our data into a Core Data database!

For our example, we’ll be importing data from a JSON file. In your apps you may want to import data from a different format, but the core idea shown here (using a Mac app to read a file and load it into a Core Data db) will still apply.

Let’s try it out! Right click on the project and select “New File”. Select “Other” category and “Empty”.

Name the file “Banks.json” and make sure to include the file in the “CoreDataTutorial2” target.

Paste the following into the new file:

[{ "name": "Bank1", "city": "City1", "state": "State1", "zip": 11111, "closeDate": "1/1/11" },
 { "name": "Bank2", "city": "City2", "state": "State2", "zip": 22222, "closeDate": "2/2/12" },
 { "name": "Bank3", "city": "City3", "state": "State3", "zip": 33333, "closeDate": "3/3/13" },
 { "name": "Bank4", "city": "City4", "state": "State4", "zip": 44444, "closeDate": "4/4/14" } ]

This is a JSON encoded string containing 4 dictionaries in an array. Each dictionary has a couple properties that correspond to the properties we have in our FailedBankInfo/FailedBankDetails objects.

If you’re a little rusty on how JSON works, check out this tutorial.

Next, we need to tell the application to copy this file into the products dictory when it builds. Select the project file, then the “CoreDataTutorial2” target. Select the “Build Phases” tab, click “Add Build Phase”, and select “Add Copy Files”. Change the destintion to “Products Directory”. Lastly, drag the “Banks.json” file into the “Add files” section.

At this point we have an application that starts up, initializes a Core Data store using our FailedBank model and classes and has a data source with the Banks.json file. Now we are going to:

  • Load the JSON file
  • Deserialize the JSON file into an Objective C array
  • Loop through the array, creating a managed object for each item
  • Save them into Core Data!

Let’s get coding! Open main.m and add the following code to the main function (at the end of the autoreleasepool block):

    NSError* err = nil;
    NSString* dataPath = [[NSBundle mainBundle] pathForResource:@"Banks" ofType:@"json"];
    NSArray* Banks = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:dataPath]
    NSLog(@"Imported Banks: %@", Banks);

So your main function should look like this now:

int main(int argc, const char * argv[])
    @autoreleasepool {
        // Create the managed object context
        NSManagedObjectContext *context = managedObjectContext();
        // Custom code here...
        // Save the managed object context
        NSError *error = nil;
        if (![context save:&error]) {
            NSLog(@"Error while saving %@", ([error localizedDescription] != nil) ? [error localizedDescription] : @"Unknown Error");
        NSError* err = nil;
        NSString* dataPath = [[NSBundle mainBundle] pathForResource:@"Banks" ofType:@"json"];
        NSArray* Banks = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:dataPath]
        NSLog(@"Imported Banks: %@", Banks);
    return 0;

This uses the new built-in NSJSONSerialization API to easily convert a JSON document into core Foundation types like NSArray, NSDictionary, etc. To learn more, check out this tutorial.

Give the application a run. You should see this print out:

2012-04-14 22:01:34.995 CoreDataTutorial2[18388:403] Imported Banks: (
        city = City1;
        closeDate = "1/1/11";
        name = Bank1;
        state = State1;
        zip = 11111;
        city = City2;
        closeDate = "2/2/12";
        name = Bank2;
        state = State2;
        zip = 22222;
        city = City3;
        closeDate = "3/3/13";
        name = Bank3;
        state = State3;
        zip = 33333;
        city = City4;
        closeDate = "4/4/14";
        name = Bank4;
        state = State4;
        zip = 44444;

So we can see we now have the data in Objective-C objects that we can easily manipulate. Now we can easily import these objects into CoreData just like we did at the end of tutorial 1.

First, add some imports you need to the top of the file:

#import "FailedBankInfo.h" 
#import "FailedBankDetails.h"

Then add the following below the code you just added earlier in main:

[Banks enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    FailedBankInfo *failedBankInfo = [NSEntityDescription
                                      inManagedObjectContext:context]; = [obj objectForKey:@"name"]; = [obj objectForKey:@"city"];
    failedBankInfo.state = [obj objectForKey:@"state"];
    FailedBankDetails *failedBankDetails = [NSEntityDescription
    failedBankDetails.closeDate = [NSDate dateWithString:[obj objectForKey:@"closeDate"]];
    failedBankDetails.updateDate = [NSDate date]; = [obj objectForKey:@"zip"]; = failedBankInfo;
    failedBankInfo.details = failedBankDetails;
    NSError *error;
    if (![context save:&error]) {
        NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
// Test listing all FailedBankInfos from the store
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"FailedBankInfo"
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (FailedBankInfo *info in fetchedObjects) {
    NSLog(@"Name: %@",;
    FailedBankDetails *details = info.details;
    NSLog(@"Zip: %@",;

This is essentially the same code we used in tutorial 1 except for the fact we are using the enumerateObjectsUsingBlock: method to loop through the array of banks and insert one bank and save the context. Then we issue a fetch request and list all the banks.

Give it a run. It should now output the array you saw earier along with this:

2012-04-14 22:15:44.149 CoreDataTutorial2[18484:403] Name: Bank1
2012-04-14 22:15:44.150 CoreDataTutorial2[18484:403] Zip: 11111
2012-04-14 22:15:44.150 CoreDataTutorial2[18484:403] Name: Bank2
2012-04-14 22:15:44.151 CoreDataTutorial2[18484:403] Zip: 22222
2012-04-14 22:15:44.152 CoreDataTutorial2[18484:403] Name: Bank3
2012-04-14 22:15:44.152 CoreDataTutorial2[18484:403] Zip: 33333
2012-04-14 22:15:44.153 CoreDataTutorial2[18484:403] Name: Bank4
2012-04-14 22:15:44.153 CoreDataTutorial2[18484:403] Zip: 44444

Ta-da! That’s your data in Core Data. The exciting part is you can totally customize the way that data comes in. Instead of the small static json file we used, you could use a much larger/a couple json files, a xml file, export a spreadsheet file as a csv file and use that, or even pipe in web service! The possibilities really are endless.

“Doctor, you’re needed in Xcode”

Now we do brain surgery. We need to take the sqlite database we just generated in you OS X console applicaiton and transplant it into the iPhone app. The easiest way to find the sqlite db is the right click on the CoreDataTutorial2 product and select “Show in Finder”.


This will open a new Finder window to location that the project got built. Here, you can see four files:

  • Banks.json – The json file with the bank information in it (remember we added the copy file build phase)
  • CoreDataTutorial2 – This is the application
  • FailedBankCD.momd (or just .mom) – this is the compiled version of the Managed Object Model (FailedBankCD.xdatamodeld)
  • CoreDataTutorial2.sqlite – the sqlite db that is generated by the application and where Core Data stores its infomration according to the model that FailedBankCD.momd specifies. If you have a viewer like this one you can even open it and view the raw data.

That “CoreDataTutorial2.sqlite” file is the juicey bit we need. Copy that file into the directory for the project from tutorial 1 then open the tutorial 1 project in Xcode.

Drag the “CoreDataTutorial2.sqlite” file from the Finder into the Xcode project (again make sure that “Copy items into destination group’s folder (if needed)” is NOT checked but “Add to targets” is checked for “FailedBanksCD”).

Lastly open up “FBCDAppDelegate.m”. Scroll down to the persistentStoreCoordinator method. Right under the NSURL *storeURL = [[self app... line, add:

if (![[NSFileManager defaultManager] fileExistsAtPath:[storeURL path]]) {
    NSURL *preloadURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"CoreDataTutorial2" ofType:@"sqlite"]];
    NSError* err = nil;
    if (![[NSFileManager defaultManager] copyItemAtURL:preloadURL toURL:storeURL error:&err]) {
        NSLog(@"Oops, could copy preloaded data");

This chunk of code checks to see if a sqlite db already exists for this app. If it doesn’t exist, it finds the path for the preloaded sqlite db we loaded and tries to copy the db to the path for the normal app db. IT’S THAT SIMPLE! Give it a run. You should see something like this:


We see our four banks and then we see that extra bank than get added from the code we wrote in tutorial 1. If you don’t see this, it’s probably because a sqlite db was already there so it’s not overwriting it. Just delete it like we did in tutorial 1.

Where to Go From Here?

You can download the code for the project here (direct download).

At this point, we have a detail view that works pretty much as efficiently as the way it did in our SQLite example. However, with Core Data, with just a couple more steps we can make it even more efficient. So in the next tutorial we cover how to do that by using NSFetchedResultsController!

If you have any questions about this tutorial or Core Data in general, please join the forum discussion below!

This is a blog post by iOS Tutorial Team member Adam Burkepile, a full-time Software Consultant and independent iOS developer. Check out his latest app Pocket No Agenda, or follow him on Twitter.

Adam Burkepile

Adam Burkepile is currently a full-time Software Consultant and independent iOS developer. If he isn’t at the computer, he’s probably getting punched in the face at Krav Maga. Check out his latest app – Pocket No Agenda. You can reach him for work or just to chat at Twitter, Github, his website, or email.

User Comments


[ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ]
  • Hi,

    I don't understand the purpose to register the json file in the Products directory, as explained here :

    Next, we need to tell the application to copy this file into the products dictory when it builds. Select the project file, then the CoreDataTutorial2 target. Select the Build Phases tab, click Add Build Phase, and select Add Copy Files. Change the destintion to Products Directory. Lastly, drag the Banks.json file into the Add files section.

    I don't really know what the Products directory stands for.
    (Nor what a "target" really means in xcode)

  • The reason to register the json file is so that it gets copied to your device (or simulator) along with the application.
  • Thanks rcasey,
    (sorry about the delay for my response) So what is the difference if you let the json along with the other files such as .h and .m files, or if you register as it is described in the tutorial? When we create a document and put it next to the .h and .m files, it cannot be overwritten later on?

    Thanks again
  • If you don't include the json file in the target, then it won't get copied to your device and the app will be unable to find it.

    The .h and .m files are compiled to create the app itself. Any supporting files like images, text files, etc need to be included in the target so they will be copied to the device as part of the application bundle. That makes them available for the app.

    Hope that helps!
  • How would one load a csv or SQL file into a core data at runtime in Swift?
    Mentioned as first option of this tutorial but not covered.
    Many Thanks
  • Hi,
    I followed tutorial with modification to use Coca App on OS X as described elsewhere.
    I am getting SQLite database preloaded. Adding to project directory and then to project.
    My app recognizes that is missign database and copies one from bundle to use further.
    The problem is that database is empty after coping. Each SQLLite database is comming with files -shm and -wal.
    It seems to me that if those files are missing the dat ainside database are nto reachable.
    Can you confirm it ? Shall I copy those files too ?
  • Hey All
    Thanks for such a good tutorial, i have two issues when i start follow this. First i have three files (DB.sqlite,DB.sqlite -shm and DB.sqlite-wal ) in this DB.sqilte file has data of some KB's instead of all data. Why please explain and when i run "exec" which is in same folder then DB.sqlite contain Double data.

    Please help
  • Take a look at the post at

    That talks about the SHM and WAL files.

    Hope that helps!
  • @rcasey
    Thanks sir it works.
  • Congratulations Adam great tutorial,
    I followed and tried to build it in Swift but lots of errors, any chance to have this great material updated?
    Nobody in any tutorial including the new books from Ray, talks about importing data from SQLite database to Xcode/CoreData/Swift, Is that so difficult?
    Well for me it is I am trying for a while and had no luck at all.
    Any input is very welcome....
  • johnpimm wrote:Regarding the loading of the data from the Banks.json file.

    When adding the file to the build phase ensure that you delete the contents of the Subpath having selected Product Directory



    This is the missing step in the tutorial. The subpath is indeed blank in the screenshot.

    Thank you.
  • Hi,

    NSManagedObjectContext *context = managedObjectContext();
    I don't understand managedObjectContext() method. managedObjectContext() method in file?

  • Thanks for the wonderful tutorial. I have followed this and some other tutorials and was able to successfully ship pre-loaded data in my app and Apple have approved my app. :)

    I need to add new entities into my core data/database. I have read about migration but not sure if it applies in the case of pre-loaded data? If not migration then should the same data model (xcappdata) be updated by adding new entities? And using a Mac app, a new Sqlite database should be created and the same should be filled with data? In the persistent store, I can detect the existence of new database and can delete the existing Sqlite database and copy the new database.

    Please provide your expert comments.

    Thanks in advance
  • Hi,

    I am not able to see the .sqlite file generated in my Products folder. I even did a command line search using 'find' but nothing!
    Can you pls help!

[ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ]

Other Items of Interest Weekly

Sign up to receive the latest tutorials from each week, and receive a free epic-length tutorial as a bonus!

Advertise with Us!

Unity Starter Kit!

We are considering writing a new starter kit on making a game in C# with Unity.

Would this be something you'd be interested in, and if so which option would you prefer?

    Loading ... Loading ...

Our Books

Our Team

Video Team

... 12 total!

Swift Team

... 10 total!

iOS Team

... 52 total!

Android Team

... 9 total!

OS X Team

... 11 total!

Sprite Kit Team

... 10 total!

Unity Team

... 9 total!

Articles Team

... 10 total!