Skip to content
This repository has been archived by the owner on Sep 19, 2018. It is now read-only.

JSONDecodable

Michael Bottone edited this page Jun 11, 2015 · 6 revisions

We mentioned before that BNRSwiftJSON provides a protocol to help model objects create instances from JSONValues. It is time to take a look at the protocol.

public protocol JSONValueDecodable {
    static func createWithJSONValue(value: JSONValue) -> Result<Self>
}

JSONValueDecodable provides a type level method called createWithJSONValu(_:). This mentod takes an instance of JSONValue, and returns a Result with an instance of Self in its .Success case. A conforming type implements this method to use a JSONValue to create an instance of itself.

Let's take a look at how the Person type conforms to JSONValueDecodable.

extension Person: JSONValueDecodable {
    public static func createWithJSONValue(value: JSONValue) -> Result<Person> {
        let name = value["name"].string
        let age = value["age"].int
        let isMarried = value["spouse"].bool
        
        return name.bind { n in
            age.bind { a in
                isMarried.map { im in
                    return self.init(name: n, age: a, spouse: im)
                }
            }
        }
    }
}

Person conforms to JSONValueDecodable in an extension. Notice that the implementation Person provides returns a Result<Person>. This return means that creating a Person will yield a Result with either an instance of Person or an informative error if a problem should occur.

The implementation of createWithJSONValue(_:) begins by making use of subscripting on JSONValue, and the uses computed properties on the resulting JSONValueResult. (Remember: that subscripting JSONValue returns a JSONValueResult.) The computed properties on JSONValueResult return a Result<T>.

let name = value["name"].string
let age = value["age"].int
let isMarried = value["spouse"].bool

For example, name is a Result<String>; that is, name is a Result with a Box holding a String in its .Success case.

After using relevant computed properties on all of the values that are needed to create an instance of the model type, we then need to figure out how to get the values out of the Results. In order to do so, we need to introduce two new methods on Result<T>: bind and map. The next section describes these methods and closes the discussion of how to use createWithJSONValue(_:).

Clone this wiki locally