Using RubyMotion with

One eventuality in the mobile development space these days is that you will, at some point, find yourself in need of a backend service for your app. You can handle this in a variety of ways:

  • • pay a company like Collective Idea to do it for you
  • • write it yourself
  • • use one of the backend-as-a-service web apps that are springing up.

One such backend-as-a-service is They have SDKs for iOS and Android as well as a RESTful api you can use from any device or platform. provides you with a way of storing data, a platform for push notifications, and even a framework for handling user accounts.

To demonstrate some of the things you can do with, I’ll be going through a sample application that lets you create a user account and then acts as a chat room with others that are using the app by making use of push notifications.

As a starting point, the application has a single view. On that view is a text field and a table view. Every time you type text into the text field and hit return that text is placed into the table view. Its your basic chat app without the remote people.

Setup the SDK

Go sign up for a account and download their SDK.

Extract the SDK into your project into ‘vendor/Parse.framework’. The vendor directory is, by convention, where you place 3rd party libraries and plugins which your app requires.

Now its a matter of adding the SDK to your project. To do this, we make a call to the vendor_project method with the path to the library and a few other pieces of information.

app.vendor_project('vendor/Parse.framework', :static, :products => ['Parse'], :headers_dir => 'Headers')

In addition to including the SDK, we’ll also need to make sure we have its dependencies added to our projects frameworks as well.

app.frameworks += %w(AudioToolbox CFNetwork SystemConfiguration MobileCoreServices Security QuartzCore)

Now that we have the SDK included in our project, we need to tell it what our application id and client key are. The best place to do this is in the didFinishLaunchingWithOptions: callback inside your app_delegate.rb file.

def application(application, didFinishLaunchingWithOptions:launchOptions)
  Parse.setApplicationId("<APPLICATION-ID>", clientKey:"<CLIENT-KEY>")

User Accounts

The first thing we want to add functionality wise is the ability to sign up and/or sign in. offers view controllers right out of the box to handle this. It makes the most sense to me for the login dialog to show up right away if we aren’t logged in. To get this to happen, we override the viewDidAppear:animated method for our ChatViewController

def viewDidAppear(animated)
  display_login unless PFUser.currentUser

The PFLogInViewController is very flexible and comes with a set of default fields that get displayed. We only want a subset of those and can adjust it by assigning to the instance fields property.

def display_login
  @login = PFLogInViewController.alloc.init
  @login.fields = PFLogInFieldsUsernameAndPassword | PFLogInFieldsLogInButton | PFLogInFieldsSignUpButton
  @login.delegate = self
  @login.signUpController.delegate = self
  self.presentModalViewController(@login, animated:true)

We want to make sure that we dismiss the login dialog if the user logs in successfully. That means overriding the logInViewController:didLogInUser: method.

def logInViewController(logIn, didLogInUser:user)

Push Notifications

The last thing we need to meet our goal is to get messages from other people. One way to handle this on iOS is through Push Notifications. We can use to send push notifications to our app but first have to obtain a application certificate from Apple for our app. That process is beyond the scope of this article but you can find more information on it here.

Once you have obtained your certificated and added it on the management interface, you need to tell your app how to handle push notifications. In this case, we only want a badge to be placed on our icon when a message is received.

def application(application, didFinishLaunchingWithOptions:launchOptions)

We also need to store the device token

def application(application, didRegisterForRemoteNotificationsWithDeviceToken:deviceToken)

Now that our app knows how it should handle push notifications when the app is in the background, we need to override the didReceiveRemoteNotification callback to handle the notifications when the app is in the foreground.

def application(application, didReceiveRemoteNotification:userInfo)

The display_message method is a helper method on the ChatViewController that adds a message to the view.

Thats all there is to it! Compile and deploy it to your device to test it out as the simulator doesn’t support push notifications. You should be able create a user account, and send messages off to others (if you have deployed it to them that is).

The source code for this app is available at You’ll have to enter in your own credentials and provide a provisioning profile in order to get it onto physical devices.

Tim Bugai


Post a Comment

(optional — will be included as a link.)
  1. Here’s a quick script to use Parse models like ActiveRecord using RubyMotion:

    May 22, 2012 at 15:02 PM
  2. Super cool! Thanks for posting. :)

    May 27, 2012 at 16:25 PM
  3. awesome post! 

    June 02, 2012 at 21:03 PM
  4. With the latest version of Parse you should use:

      app.libs << “-lsqlite3”
      app.frameworks += [

    November 24, 2012 at 11:31 AM
  5. Hi,

    Any idea why I would get a uninitialized constant error when I try to use the Social Buttons ?

    @login.fields = PFLogInFieldsUsernameAndPassword | PFLogInFieldsLogInButton | PFLogInFieldsSignUpButton | PFLogInFieldsFacebookButton | PFLogInFieldsTwitterButton

    December 08, 2012 at 3:07 AM
  6. I guess the docs are a bit off, the constants below work
      @login.fields = PFLogInFieldsUsernameAndPassword | PFLogInFieldsLogInButton | PFLogInFieldsSignUpButton | PFLogInFieldsFacebook | PFLogInFieldsTwitter

    December 08, 2012 at 3:19 AM
  7. Thanks for posting. Probably saved me several hours. Your website has been bookmarked!

    Martin Lockett
    Martin Lockett
    June 24, 2015 at 12:42 PM