Using RubyMotion with Parse.com

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 Parse.com. They have SDKs for iOS and Android as well as a RESTful api you can use from any device or platform. Parse.com 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 Parse.com, 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 Parse.com 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 Parse.com 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("", clientKey:"")
end

User Accounts

The first thing we want to add functionality wise is the ability to sign up and/or sign in. Parse.com 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
end

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)
end

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)
  @login.dismissModalViewControllerAnimated(true)
end

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 Parse.com 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 Parse.com 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)
  ...
  application.registerForRemoteNotificationTypes(UIRemoteNotificationTypeBadge)
  ...
end

We also need to store the device token

def application(application, didRegisterForRemoteNotificationsWithDeviceToken:deviceToken)
  PFPush.storeDeviceToken(deviceToken)
  PFPush.subscribeToChannelInBackground("chat")
end

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)
  @chat_window.display_message(userInfo)
end

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 http://github.com/collectiveidea/rubymotion-parsedotcom-chat.git. You’ll have to enter in your own parse.com credentials and provide a provisioning profile in order to get it onto physical devices.

tim@collectiveidea.com

Comments

  1. May 22, 2012 at 15:02 PM

    Here’s a quick script to use Parse models like ActiveRecord using RubyMotion: https://github.com/adelevie/ParseModel

  2. calebcohoon@gmail.com
    calebhc
    May 27, 2012 at 16:25 PM

    Super cool! Thanks for posting. :)

  3. June 02, 2012 at 21:03 PM

    awesome post! 

  4. November 24, 2012 at 11:31 AM

    With the latest version of Parse you should use:

      app.libs << “-lsqlite3”
    app.frameworks += [
    ‘Accounts’,
    ‘Social’,
    ‘AdSupport’,
    ‘AudioToolbox’,
    ‘CFNetwork’,
    ‘SystemConfiguration’,
    ‘MobileCoreServices’,
    ‘Security’,
    ‘QuartzCore’,
    ‘StoreKit’]

  5. imran.iansari@gmail.com
    iansari
    December 08, 2012 at 3:07 AM

    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
  6. December 08, 2012 at 3:19 AM

    I guess the docs are a bit off, the constants below work

    @login.fields = PFLogInFieldsUsernameAndPassword | PFLogInFieldsLogInButton | PFLogInFieldsSignUpButton | PFLogInFieldsFacebook | PFLogInFieldsTwitter

  7. martin@lockett.com
    Martin Lockett
    June 24, 2015 at 12:42 PM

    Thanks for posting. Probably saved me several hours. Your website has been bookmarked!