Tag Archives: Core Data

Core Data Nugget #1: How to speak Core Data

In this screencast I’ll talk you through the lingo of Core Data: those scary classes and expressions that you’ll frequently come across. In fact, this is the start of a new series:

Core Data Nuggets are bite-sized chunks about the framework. Dip in and out or watch them all in a row and learn how this super complicated framework works and what it has to offer.

Don’t get overwhelmed by Core Data: it wants to help – it’s just not designed with humans in mind.

As always, enjoy!

How to Tear Down your Core Data Stack in iOS

In this screencast I will show you how to tear down your Core Data Stack. Documentation on this topic is a little sketchy to say the least.

We’ll create a new Master/Detail app and implement a button that will remove the store file and reset the entire stack – without nasty error messages or app crashes. The app will work on iOS 7.1 and iOS 6. I’m using Xcode 5.1 in this demo. The principles of course apply just as much to Mac Development.

You can read more in my companion article here: http://pinkstone.co.uk/how-to-tear-down-your-core-data-stack/

There’s also a GitHub project that shows the full app (find the link in the same article).


How to use Core Data with multiple Store Files

Sometimes it can be useful to split your Core Data Store File across multiple files. For example, one file could live on the local file system, while the other could live in iCloud.

We can do this by telling the Xcode Model Editor to add more than one Configuration, each of which can be allocated certain Entities. Each Configuration can be configured to use a separate store file.

Consider this example code which is provided by the Xcode 4.6 templates to initiate the Persistent Store Coordinator:

Notice the absence of a Configuration in the addPersistentStoreWithType method. You can create Configurations by click-holding the big PLUS button that let’s you add Entities by default. GIve them a meaningful name, then drag-and-drop in your Entities:

Two Stores Model Editor

Next you’ll replace the code above with something like this, adding more than one store file to your Persistent Store Coordinator:

Now you’ll work with two store files in the same Managed Object Context. This also means that whatever operation you call on the context (save for example) will be executed on both store files.

Demo Project

I’ve added a Demo Project to GitHub which demonstrates this in Mac OS X:

How to remove a Core Data Model Version

Core Data can handle several versions of your Model. It’s easy to add a version (via Editor – Add Model Version) and set it active, but it’s not so easy to remove a version you no longer need.

Thankfully there is a way to delete version files which goes a long way to declutter your brain. The secret lies in the fact that the .xcdatamodeld file is actually a Package and can contain more than one file. It’s like the .app extension which isn’t just one file. I never knew this!

To explore, select your versioned .xcdatamodeld file, right-click it and select “Show in Finder”. Once in there right-click it again and select “Show Package Contents”. Surprise – here are all your Model Versions. Before you go on a mad deleting spree, head back to Xcode and do the following:

  1. activate a Model Version that you want to keep (by going to the top level .xcdatamodeld entry, then select it under “Versioned Core Data Model”)
  2. next remove the entire file from your project (just the reference… do not move to trash)
  3. head back to the Finder and delete the files inside the Package you no longer want
  4. go back to Xcode and add the .xcdatamodeld file again

Voila – now all your unnecessary Model Versions are gone. Perhaps in a future version of Xcode there will be an easier way to do this, but as of Xcode 4.6.2 (April 2013) there is not.

Further Reading

Thanks to David Avendasora for this wonderfully simple explanation on Stack Overflow: http://stackoverflow.com/questions/7708392/how-to-delete-an-old-unused-data-model-version-in-xcode-4

How to create a Fetch Request in the Xcode Model Editor

You can create Fetch Requests in the Xcode model editor, including a Predicate. These are somewhat easier to setup. To create one, select your .xcdatamodeld file, then head over to Editor – Add Fetch Request. Give it a catchy name and a filter property, and much of the above code becomes obsolete.

Here’s how you can retrieve one of those in code:

Note that to retrieve your Fetch Request Template you need a reference to your Managed Object Model as well as your context. The easiest way to grab hold of it in an iOS app is to pass it in on a property, just like we did with self.managedoObjectContext.

How to pass data from the App Delegate to your Top View Controller

If the App Delegate has something that your top view controller needs then you simply pass it the required object via a property set on the top view controller. This is easy when your top view controller is also the root view controller.

However, when you embed your top view controller in a Navigation Controller, and perhaps that one is also embedded in a Tab Bar Controller, then this array isn’t quite so easy to figure out (and I must admit that I always forget how to do this when a new challenge arises).

So here’s how this works. In this example, the thing that’s displayed is called MyViewController, which is embedded in a Navigation Controller. I’m passing it the App Delegate’s self.managedObjectContext which is defined as a property on MyViewController.

We call this in the applicationDidFinishLaunching method, just before the return statement.

How to convert a Persistent Store from XML to SQLite in Core Data

By default Mac Apps use XML as store type when saving in Core Data, even though it can use other formats – such as SQLite, which is the default on iOS. Here’s a way to quickly convert one into the other.

Note that this is designed as a one-off operation to create a new store file which can be used in another application. Once run, comment the code out and either change your store file, or take the store file and use it in another app.

Add this code to the AppDelegate.m file in the persistenStore method (just before the return statement):

For more information on how to do this in context, check out Simon Allardice’s superb course Core Data for iOS and OS X on Lynda.com.

Binding an NSTableView to Core Data without code

Mountain Lion LogoI was excited to find out that it is possible to write a Mac App with Core Data completely without code! This magic is possible with something that’s not available in iOS (yet) called Cocoa Bindings.

You provide the user controls you need in Xcode, then control-drag your way to extensive functionality and happiness. Before I forget, I thought I’d better make some notes.

Here’s a step-by-step list:

  • Using Xcode, create a new Mac Cocoa Application with Core Data
  • Setup your entities and properties in your Core Data Model (.xcdatamodeld)
  • Create relationships between Entities if desired
  • Select all Entities and create custom classes from them (using Editor – create NSManagedObject Subclasses)

Drag our friend the Array Controller onto the Object’s Bar. If you have multiple Entities, you need a separate Array Controller for each one. Change the labels to tell them apart (select a different file and go back to the xib in order for those labels to be visible – it’s a bug in Xcode).

Now bind the Array Controller and Core Data Managed Object Context together:

  • Select your Array Controller, then go to the Bindings Inspector (second from the right)
  • Under Parameters, head over to the Managed Object Context and bind to the App Delegate (as that’s where Xcode has kindly prepared our Core Data stack)
  • In Model Key Path, type self.managedObjectContext (this should self complete)
  • In the Attributes Inspector, tell the controller that we’re using an Entity instead of a Class, then enter the Entity (it’s the one you’ve created in the data model)
  • While you’re here, tick the “Prepares Content” check box if you want the table view to be populated automatically

Add a Table View to your window and bind it to the Array Controller:

  • Select the Table View (inside the Scroll View) and head over to the Bindings Inspector
  • Under Table Content, select Bind To your Array Controller
  • Now select the actual Table Column you want to fill with data, and still inside the Bindings Inspector under Value, bind the column to your Array Controller
  • In the field for Model Key Path, type the attribute/property you’d like to see in this column (you’ve defined this in the data model)
  • Repeat the process for each column you want to fill with data

To add data to your table:

  • Add a couple of Gradient Buttons to your window
  • Make one the “Add” and one the “Delete” button
  • Hook up each button to the Array Controller via control drag, selecting add and remove respectively

Congratulations: You’ve just created an editable Table View, hooked up to Core Data without a single line of code!

Let’s create a functional SAVE menu item

If you quit the app (rather than running it again from Xcode), all your data will save. However we can implement a manual save action with ease. The menu item itself is there by default, all we need to do is hook it up to the App Delegate and bind it to the save function.

In the Object Sidebar, select Main Menu, then select File – Save (which will expand the item in the sidebar too). From the save menu option, control drag to the App Delegate and select saveAction.

How to “quick save” in Core Data

The easiest way to access a readily available save method is by importing AppDelegate into the class that wants to execute the save. Then we call a method in AppDelegate:

No reference to fetchedResultsController or managedObjectContext or any complex &error statements.