Using Core Data in iOS with RubyMotion

Learn how to use Core Data in a simple RubyMotion app. By Gavin Morrice.

Leave a rating/review
Save for later
Share

If you’re looking to add persistence to your iOS or OS X app, Core Data is great choice — and implementing it in RubyMotion is surprisingly simple.

In this tutorial, you’ll use Core Data to add persistence to the Pomotion timer I showed you in how to make in my RubyMotion Tutorial for Beginners series.

If you have a good understanding of RubyMotion, feel free to download the complete code from the GitHub repository and start from there.

Otherwise, I’d suggest working through those two tutorials before starting this one.

You’ll need the following to get the most out of this RubyMotion tutorial:

  • Experience developing for iOS in Objective-C
  • Basic understanding of Ruby
  • Basic knowledge of CSS
  • Basic experience using Terminal

Prior experience with Core Data or ActiveRecord would also be a huge plus, but neither is essential.

Getting Started

First, make sure you have the final project from the previous tutorial series or grab it from GitHub.

Open Terminal, switch to the root directory of the application, and make sure the app builds successfully by running the following command:

rake device_name="iPhone 4s"
Note: RubyMotion 3 includes a new option device_name for the rake command that lets you specify which device simulator the app will run on. I prefer to use the iPhone 4s simulator because it’s smaller and I can see everything on the screen.

If your screen looks like this, great — If it doesn’t, make sure you’ve followed the installation instructions and completed all of the steps in the previous Pomotion tutorials.

Your starting point app should look like this.

Your starting point app should look like this.

Once you have Pomotion running, you’re ready to begin.

Additionally, you may see an error something like Bundler::GemNotFound: Couldn’t find sass-3.4.2 in any of the sources. If you encounter this issue, you can explicitly install Sass v3.4.2 with the following: gem install sass -v 3.4.2

Dependency Updates: If it has been a while since you last used RubyMotion, you may need to update some of your gems. Specifically, you may need to update the bundler gem. You can do so by running the following command in Terminal: gem update bundler.

Adding the Tasks Button

You’re going to add a tasks list to the Pomotion app. Think of this as a user’s daily TODO list where users add and remove tasks, as well as select a task to work on.

Users access the tasks list by tapping a button in the navigation bar. So, you’ll start by adding that button.

Using your favorite text editor, open app/controllers/main_view_controller.rb and add the following lines under the timer_button method definition.

def tasks_button
  @tasks_button ||= UIBarButtonItem.alloc.initWithImage(tasks_image, 
    style: UIBarButtonItemStylePlain, target: self, action: nil)
end

def tasks_image
  @tasks_image ||= UIImage.imageNamed('todo.png')
end

Here you’ve defined two properties on the MainViewController class: a UIBarButtonItem named tasks_button, and a UIImage named tasks_image.

Before you run these changes, you’ll need to add the image file referenced in the tasks_image method above to your app’s resources.

Download this file and save it to your application’s resources directory as todo.png.

Still in app/controllers/main_view_controller.rb, add this method below the tasks_image method:

def viewDidLoad
  super
  self.title = "Pomotion"
  self.navigationItem.rightBarButtonItem = tasks_button
end

This adds the tasks_button to MainViewController’s navigation bar. Build and run your app the same way you did the last time to see the changes:

rake device_name="iPhone 4s"

Main Screen with blue tasks button

Looking good so far! However, the color scheme for this app is red, white and green. That blue tint on the tasks_button is a bit clashy, don’t you think? Good thing you can change that!

You might remember from the previous Pomotion tutorial that Pomotion uses PixateFreestyle to add CSS styles to your app’s views. This means that you’ll find style definition in a CSS file named resources/default.css.

Open resources/default.css and add the following line to the navigation-bar selector:

-ios-tint-color: white;

This changes the tint color of the navigation bar to white. To learn more, check out the Pixate reference.

Save the file then build and run the app again with rake device_name="iPhone 4s". The tasks button should now have a white tint instead of blue.

Main screen with white tasks button

Wasn’t that easy? :]

Try tapping the tasks_button. Nada. Why isn’t it responding? Oh, because you haven’t defined an action to be called when it’s tapped.

Adding the Tasks List Screen

In Terminal, create a new file in the app/controllers directory named tasks_view_controller.rb:

touch app/controllers/tasks_view_controller.rb

Open the file in your text editor.

Declare TasksViewController as a subclass of UITableViewController like the following:

class TasksViewController < UITableViewController

end

Save the file, and open main_view_controller.rb and add the following just after timer_button_tapped:.

def tasks_button_tapped(sender)
  tasks_controller = TasksViewController.alloc.initWithNibName(nil, bundle: nil)
  navigationController.pushViewController(tasks_controller, animated: true)  
end

This displays the tasks list when the user taps the tasks_button.

Now wire up this method to the action: parameter in tasks_button with this:

def tasks_button
  @tasks_button ||= UIBarButtonItem.alloc.initWithImage(tasks_image, 
    style: UIBarButtonItemStylePlain, target: self, action: 'tasks_button_tapped:')
end

Build and run again to launch the app in the simulator

rake device_name="iPhone 4s"

This time, when you tap the tasks_button you should see an empty table view that looks like this:

Pomotion tasks list with no tasks

Now you're making progress! The UI is mostly configured and now it's time to drill down into the inner workings and make it actually do something more than look pretty.

Populating the Tasks List with Real Data

Installing CDQ

Here comes the fun part...

To use Core Data in your app, you'll be using the Core Data Query gem (or cdq, for short). cdq makes it really easy to get started with Core Data in RubyMotion with just a few lines of code.

I showed you how to install gems to your project in RubyMotion Tutorial for Beginners: Part 1, but you can read the Pixate Freestyle section if you need a refresher.

Open your Gemfile and add the following line:

gem 'cdq'

Then make sure it's installed by running this command in Terminal:

$ bundle install

Now that cdq is installed, run the following command in Terminal to complete the installation:

cdq init

The cdq init command does a couple of things, and it's quite important that you understand them both.

First, it creates an initial schema file named 0001_initial.rb in a new directory named schemas. These schema files are where you define and manage your application's database structure.

Each time you need to make a change to one of the tables, you create a new schema file that reflects how the new database should look. As long as the versions are not too different from each other, Core Data automatically migrates your database and updates the structure without you having to do anything else.

The second thing cdq init does is that it adds another line to the bottom of your Rakefile, like this:

task :"build:simulator" => :"schema:build"

In short, this makes sure that each time you build the app to run in the simulator, the rake schema:build command also runs to keep the schema up to date.

This is extremely helpful, but there's a potential pitfall: If you're deploying to an iOS device instead of the simulator, this command doesn't run automatically — you'll have to run it manually from Terminal by running:

rake "schema:build"

Good to know!

Now, open app/app_delegate.rb and include CDQ by adding the following line just below AppDelegate:

  include CDQ

And finally, add the following line to the start of application:didFinishLaunchingWithOptions

  cdq.setup

And that's it for the installation. Next up is setting up your first data model.