No commit activity in last 3 years
No release in over 3 years
Turn JSON nodes into rich Ruby objects
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

>= 0
 Project Readme

motion-json-decoder

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

Installation

  • 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:

{
  "people":
    [
      {
        "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
end

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

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 = Person.new(person_hash)
  NSLog "Adding #{person.first_name}..."
  names << person.full_name
end

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
end

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

Collections

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.