Treat JSON nodes as rich objects.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Treat a parsed JSON response as a graph of proper Ruby objects, rather than plain hashes and arrays.


  • Add motion-json-decoder to your Gemfile and run bundle.
  • Add require 'motion-json-decoder to your Rakefile.

Basic Example

Let's say you have a RubyMotion app which parses this response from the server:

        "first_name": "John",
        "last_name": "Smith",
        "date_of_birth": "1980-01-03"
        "first_name": "Joe",
        "last_name": "Bloggs",
        "date_of_birth": "1967-10-11"

i.e. a people collection which contains two person nodes.

There may be a number of place in your app where you want to display a person's full name:

names = []
json['people'].each do |person|
  full_name = person['first_name'] + ' ' + person['last_name']
  names << full_name

But doing this in multiply places isn't very DRY. You could write a helper method, but where should that code live?

motion-json-decoder allows the creation of mappings between the nodes in a JSON response, and simple objects. Just include the module in your class and use the simple DSL to declare your fields:

class Person
  include JSONDecoder::Node

  field :first_name
  field :last_name

  def full_name
    first_name + ' ' + last_name

You can then treat person as a simple object, by passing a hash when instantiating a new node object:

names = []
json['people'].each do |person_hash|
  person =
  NSLog "Adding #{person.first_name}..."
  names << person.full_name

Extra Protection

Under the hood, motion-json-decoder uses Hash#fetch rather than Hash#[], so if you call a field which doesn't exist, you'll get an exception right away, rather than a potentially difficult-to-debug nil return value.

Checking for Presence

You can check if the node contains a particular key:

class Person
  include JSONDecoder::Node

  field :first_name
  field :last_name
  field :middle_name

person ={'first_name' => 'Andy', 'last_name' => nil})
person.first_name? #-> true
person.last_name? #-> true (even though it's nil)
person.middle_name? #-> false


You can specify that a nodes contains a collection of other 'resources' rather than a simple literals:

collection :organisations, :class_name -> { Organisation }

class_name parameter should be another class which includes the JSONDecoder::Node module.

When you call json.people, rather than array of hashes, you'll get an array of Organisation objects.

The use of the lambda (->) is to avoid dependency resolution problems at compile time.