{"id":15405369,"url":"https://github.com/andyw8/motion-json-decoder","last_synced_at":"2025-09-12T10:44:41.973Z","repository":{"id":7042017,"uuid":"8319569","full_name":"andyw8/motion-json-decoder","owner":"andyw8","description":"Treat JSON nodes as rich objects.","archived":false,"fork":false,"pushed_at":"2013-02-21T15:50:41.000Z","size":136,"stargazers_count":10,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-29T05:51:15.445Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andyw8.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-02-20T18:44:13.000Z","updated_at":"2022-04-14T21:49:50.000Z","dependencies_parsed_at":"2022-09-22T11:30:53.196Z","dependency_job_id":null,"html_url":"https://github.com/andyw8/motion-json-decoder","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andyw8%2Fmotion-json-decoder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andyw8%2Fmotion-json-decoder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andyw8%2Fmotion-json-decoder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andyw8%2Fmotion-json-decoder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andyw8","download_url":"https://codeload.github.com/andyw8/motion-json-decoder/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248710434,"owners_count":21149192,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-01T16:16:25.628Z","updated_at":"2025-04-17T00:51:57.764Z","avatar_url":"https://github.com/andyw8.png","language":"Ruby","readme":"motion-json-decoder\n===================\n\nTreat a parsed JSON response as a graph of proper Ruby objects, rather than plain hashes and arrays.\n\nInstallation\n------------\n* Add `motion-json-decoder` to your Gemfile and run `bundle`.\n* Add `require 'motion-json-decoder` to your Rakefile.\n\nBasic Example\n-------------\n\nLet's say you have a RubyMotion app which parses this response from the server:\n\n    {\n      \"people\":\n        [\n          {\n            \"first_name\": \"John\",\n            \"last_name\": \"Smith\",\n            \"date_of_birth\": \"1980-01-03\"\n          },\n          {\n            \"first_name\": \"Joe\",\n            \"last_name\": \"Bloggs\",\n            \"date_of_birth\": \"1967-10-11\"\n          }\n        ]\n    }\n\ni.e. a *people* collection which contains two *person* nodes.\n\nThere may be a number of place in your app where you want to display a person's full name:\n\n    names = []\n    json['people'].each do |person|\n      full_name = person['first_name'] + ' ' + person['last_name']\n      names \u003c\u003c full_name\n    end\n\nBut doing this in multiply places isn't very DRY. You could write a helper method, but where should that code live?\n\n*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:\n\n    class Person\n      include JSONDecoder::Node\n\n      field :first_name\n      field :last_name\n\n      def full_name\n        first_name + ' ' + last_name\n      end\n    end\n\nYou can then treat person as a simple object, by passing a hash when instantiating a new node object:\n\n    names = []\n    json['people'].each do |person_hash|\n      person = Person.new(person_hash)\n      NSLog \"Adding #{person.first_name}...\"\n      names \u003c\u003c person.full_name\n    end\n\nExtra Protection\n----------------\n\nUnder 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.\n\nChecking for Presence\n---------------------\nYou can check if the node contains a particular key:\n\n    class Person\n      include JSONDecoder::Node\n\n      field :first_name\n      field :last_name\n      field :middle_name\n    end\n\n    person = Person.new({'first_name' =\u003e 'Andy', 'last_name' =\u003e nil})\n    person.first_name? #-\u003e true\n    person.last_name? #-\u003e true (even though it's nil)\n    person.middle_name? #-\u003e false\n\nCollections\n------------\n\nYou can specify that a nodes contains a collection of other 'resources' rather than a simple literals:\n\n    collection :organisations, :class_name -\u003e { Organisation }\n\nclass_name parameter should be another class which includes the `JSONDecoder::Node` module.\n\nWhen you call json.people, rather than array of hashes, you'll get an array of Organisation objects.\n\nThe use of the lambda (`-\u003e`) is to avoid dependency resolution problems at compile time.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandyw8%2Fmotion-json-decoder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandyw8%2Fmotion-json-decoder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandyw8%2Fmotion-json-decoder/lists"}