<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <id>tag:davidcaunt.co.uk,2014:/feed</id>
  <link rel="alternate" type="text/html" href="http://davidcaunt.co.uk"/>
  <link rel="self" type="application/atom+xml" href="http://davidcaunt.co.uk/feed"/>
  <title>David Caunt</title>
  <updated>2016-07-14T10:59:16-07:00</updated>
  <author>
    <name>David Caunt</name>
    <uri>http://davidcaunt.co.uk</uri>
  </author>
  <generator>Svbtle.com</generator>
  <entry>
    <id>tag:davidcaunt.co.uk,2014:Post/himotoki-tutorial</id>
    <published>2016-07-14T10:59:16-07:00</published>
    <updated>2016-07-14T10:59:16-07:00</updated>
    <link rel="alternate" type="text/html" href="http://davidcaunt.co.uk/himotoki-tutorial"/>
    <title>Himotoki Tutorial</title>
    <content type="html">&lt;p&gt;&lt;a href="https://github.com/ikesyo/Himotoki"&gt;Himotoki&lt;/a&gt; is a simple yet powerful library for decoding JSON. From the project page:&lt;/p&gt;
&lt;blockquote class="large"&gt;&lt;p&gt;Himotoki (紐解き) is a type-safe JSON decoding library purely written in Swift. This library is highly inspired by popular JSON parsing libraries in Swift: Argo and ObjectMapper.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This article provides a brief tutorial and Xcode Playground to help learn how to use it. You can clone the Playground from &lt;a href="https://github.com/dcaunt/himotoki-playground"&gt;GitHub here&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id="basic-decoding_1"&gt;&lt;a class="head_anchor" href="#basic-decoding_1"&gt;&amp;nbsp;&lt;/a&gt;Basic Decoding&lt;/h1&gt;
&lt;p&gt;As you can see from the Himotoki README, creating a model and specifying how to decode it from JSON is fairly straightforward: &lt;/p&gt;

&lt;pre&gt;&lt;code class="prettyprint"&gt;struct Group: Decodable {
    let name: String
    let floor: Int
    let locationName: String
    let optional: [String]?

    // MARK: Decodable

    static func decode(e: Extractor) throws -&amp;gt; Group {
        return try Group(
            name: e &amp;lt;| &amp;quot;name&amp;quot;,
            floor: e &amp;lt;| &amp;quot;floor&amp;quot;,
            locationName: e &amp;lt;| [ &amp;quot;location&amp;quot;, &amp;quot;name&amp;quot; ], // Parse nested objects
            optional: e &amp;lt;||? &amp;quot;optional&amp;quot; // Parse optional arrays of values
        )
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Himotoki can decode any generic type &lt;code class="prettyprint"&gt;T&lt;/code&gt;  conforming to its &lt;code class="prettyprint"&gt;Decodable&lt;/code&gt; protocol using the operators below. We’ll see how to implement Decodable in our own code later.&lt;/p&gt;

&lt;table&gt;&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left;"&gt;Operator&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Decode element as&lt;/th&gt;
&lt;th style="text-align: left;"&gt;Remarks&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;&amp;lt;&amp;#124;&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code class="prettyprint"&gt;T&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;A value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;&amp;lt;&amp;#124;?&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code class="prettyprint"&gt;T?&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;An optional value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;&amp;lt;&amp;#124;&amp;#124;&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code class="prettyprint"&gt;[T]&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;An array of values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;&amp;lt;&amp;#124;&amp;#124;?&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code class="prettyprint"&gt;[T]?&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;An optional array of values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;&amp;lt;&amp;#124;-&amp;#124;&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code class="prettyprint"&gt;[String: T]&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;A dictionary of values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left;"&gt;&lt;code&gt;&amp;lt;&amp;#124;-&amp;#124;?&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;&lt;code class="prettyprint"&gt;[String: T]?&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left;"&gt;An optional dictionary of values&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h1 id="advanced-decoding_1"&gt;&lt;a class="head_anchor" href="#advanced-decoding_1"&gt;&amp;nbsp;&lt;/a&gt;Advanced Decoding&lt;/h1&gt;
&lt;p&gt;Let’s assume we have the following JSON representing a series of musical bands:&lt;/p&gt;

&lt;pre&gt;&lt;code class="prettyprint"&gt;{
  &amp;quot;objects&amp;quot;: [
    {
      &amp;quot;name&amp;quot;: &amp;quot;Beatles&amp;quot;,
      &amp;quot;homepage&amp;quot;: &amp;quot;http://www.thebeatles.com/&amp;quot;,
      &amp;quot;active&amp;quot;: &amp;quot;inactive&amp;quot;,
      &amp;quot;members&amp;quot;: [
        {
          &amp;quot;name&amp;quot;: &amp;quot;George Harrison&amp;quot;,
          &amp;quot;birth_date&amp;quot;: &amp;quot;1943-02-25&amp;quot;
        },
        {
          &amp;quot;name&amp;quot;: &amp;quot;John Lennon&amp;quot;,
          &amp;quot;birth_date&amp;quot;: &amp;quot;1940-10-09&amp;quot;
        },
        {
          &amp;quot;name&amp;quot;: &amp;quot;Paul McCartney&amp;quot;,
          &amp;quot;birth_date&amp;quot;: &amp;quot;1942-06-18&amp;quot;
        },
        {
          &amp;quot;name&amp;quot;: &amp;quot;Ringo Starr&amp;quot;,
          &amp;quot;birth_date&amp;quot;: &amp;quot;1940-07-07&amp;quot;
        }
      ]
    },
    {
      &amp;quot;name&amp;quot;: &amp;quot;The Rolling Stones&amp;quot;,
      &amp;quot;active&amp;quot;: &amp;quot;active&amp;quot;,
      &amp;quot;members&amp;quot;: [
        {
          &amp;quot;name&amp;quot;: &amp;quot;Charlie Watts&amp;quot;,
          &amp;quot;birth_date&amp;quot;: &amp;quot;1941-06-02&amp;quot;
        },
        {
          &amp;quot;name&amp;quot;: &amp;quot;Keith Richards&amp;quot;,
          &amp;quot;birth_date&amp;quot;: &amp;quot;1943-12-18&amp;quot;
        },
        {
          &amp;quot;name&amp;quot;: &amp;quot;Mick Jagger&amp;quot;,
          &amp;quot;birth_date&amp;quot;: &amp;quot;1943-07-26&amp;quot;
        },
        {
          &amp;quot;name&amp;quot;: &amp;quot;Ronnie Wood&amp;quot;,
          &amp;quot;birth_date&amp;quot;: &amp;quot;1947-06-01&amp;quot;
        }
      ]
    }
  ],
  &amp;quot;last_updated&amp;quot;: &amp;quot;2016-05-17T22:43:04.000000+00:00&amp;quot;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This JSON is straightforward, yet interesting enough to give our model several requirements. There are a couple of different date formats (&lt;code class="prettyprint"&gt;last_updated&lt;/code&gt; and &lt;code class="prettyprint"&gt;birth_date&lt;/code&gt;), and a field which can be represented as an enumerated type (&lt;code class="prettyprint"&gt;active&lt;/code&gt;). The optional &lt;code class="prettyprint"&gt;homepage&lt;/code&gt; property should really be represented as an &lt;code class="prettyprint"&gt;NSURL&lt;/code&gt;. Finally, this structure represents a generic collection of &lt;code class="prettyprint"&gt;objects&lt;/code&gt;, so it would be nice to re-use that collection for other types.&lt;/p&gt;
&lt;h3 id="models_3"&gt;&lt;a class="head_anchor" href="#models_3"&gt;&amp;nbsp;&lt;/a&gt;Models&lt;/h3&gt;
&lt;p&gt;We define the following &lt;code class="prettyprint"&gt;struct&lt;/code&gt; types to model our data.&lt;/p&gt;

&lt;pre&gt;&lt;code class="prettyprint"&gt;struct BandResponse {
    let objects: [Band]
    let lastUpdated: NSDate?
}

struct Band {
    enum Status: String {
        case Active = &amp;quot;active&amp;quot;
        case Hiatus = &amp;quot;hiatus&amp;quot;
        case Disbanded = &amp;quot;inactive&amp;quot;
    }

    let name: String
    let members: [BandMember]
    let homepageURL: NSURL?
    let status: Status
}

struct BandMember {
    let name: String
    let birthDate: NSDate
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id="decodable_3"&gt;&lt;a class="head_anchor" href="#decodable_3"&gt;&amp;nbsp;&lt;/a&gt;Decodable&lt;/h3&gt;
&lt;p&gt;Through the power of generics, Himotoki can automatically decode extracted values from JSON to their correct types. To add support for &lt;code class="prettyprint"&gt;NSURL&lt;/code&gt;, we define an Extension:&lt;/p&gt;

&lt;pre&gt;&lt;code class="prettyprint"&gt;extension NSURL: Decodable {
    public static func decode(e: Extractor) throws -&amp;gt; Self {
        let rawValue = try String.decode(e)

        guard let result = self.init(string: rawValue) else {
            throw DecodeError.Custom(&amp;quot;Error parsing URL from string&amp;quot;)
        }

        return result
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We also need to implement Decodable for our own types, &lt;code class="prettyprint"&gt;Band&lt;/code&gt;, &lt;code class="prettyprint"&gt;BandMember&lt;/code&gt; and &lt;code class="prettyprint"&gt;BandResponse&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class="prettyprint"&gt;extension BandResponse: Decodable {
    static func decode(e: Extractor) throws -&amp;gt; BandResponse {
        return try BandResponse(objects: e &amp;lt;|| &amp;quot;objects&amp;quot;,
            lastUpdated: DateTimeTransformer.apply(e &amp;lt;|? &amp;quot;last_updated&amp;quot;)
        )
    }
}

extension BandMember: Decodable {
    static func decode(e: Extractor) throws -&amp;gt; BandMember {
        return try BandMember(name: e &amp;lt;| &amp;quot;name&amp;quot;,
            birthDate: DateTransformer.apply(e &amp;lt;| &amp;quot;birth_date&amp;quot;)
        )
    }
}

extension Band: Decodable {
    static func decode(e: Extractor) throws -&amp;gt; Band {
        return try Band(name: e &amp;lt;| &amp;quot;name&amp;quot;,
            members: e &amp;lt;|| &amp;quot;members&amp;quot;,
            homepageURL: e &amp;lt;|? &amp;quot;homepage&amp;quot;,
            status: e &amp;lt;| &amp;quot;active&amp;quot;
        )
    }
}

extension Band.Status: Decodable {}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that Himotoki provides a protocol extension for &lt;code class="prettyprint"&gt;RawRepresentable&lt;/code&gt; types, so conforming to &lt;code class="prettyprint"&gt;Decodable&lt;/code&gt; is enough as enums with a &lt;code class="prettyprint"&gt;RawValue&lt;/code&gt; conform to this protocol.&lt;/p&gt;

&lt;p&gt;Finally, we implement two transformers for decoding the two date formats:&lt;/p&gt;

&lt;pre&gt;&lt;code class="prettyprint"&gt;public let DateTransformer = Transformer&amp;lt;String, NSDate&amp;gt; { dateString throws -&amp;gt; NSDate in
    let dateFormatter = NSDateFormatter()
    dateFormatter.locale = NSLocale(localeIdentifier: &amp;quot;en_US_POSIX&amp;quot;)
    dateFormatter.dateFormat = &amp;quot;yyyy-MM-dd&amp;quot;
    dateFormatter.timeZone = NSTimeZone(abbreviation: &amp;quot;UTC&amp;quot;)

    if let date = dateFormatter.dateFromString(dateString) {
        return date
    }

    throw customError(&amp;quot;Invalid date string: \(dateString)&amp;quot;)
}

public let DateTimeTransformer = Transformer&amp;lt;String, NSDate&amp;gt; { dateString throws -&amp;gt; NSDate in
    let dateFormatter = NSDateFormatter()
    dateFormatter.locale = NSLocale(localeIdentifier: &amp;quot;en_US_POSIX&amp;quot;)
    dateFormatter.dateFormat = &amp;quot;yyyy-MM-dd&amp;#39;T&amp;#39;HH:mm:ss.SSSZ&amp;#39;&amp;quot;
    dateFormatter.timeZone = NSTimeZone(abbreviation: &amp;quot;UTC&amp;quot;)

    if let date = dateFormatter.dateFromString(dateString) {
        return date
    }

    throw customError(&amp;quot;Invalid datetime string: \(dateString)&amp;quot;)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These only vary in the &lt;code class="prettyprint"&gt;dateFormat&lt;/code&gt; provided to the &lt;code class="prettyprint"&gt;NSDateFormatter&lt;/code&gt;, so we could probably factor this out.&lt;/p&gt;

&lt;p&gt;If all date representations in JSON have the same format, we can define an &lt;code class="prettyprint"&gt;Extension&lt;/code&gt; on &lt;code class="prettyprint"&gt;NSDate&lt;/code&gt; to implement &lt;code class="prettyprint"&gt;Decodable&lt;/code&gt;, just as we did with &lt;code class="prettyprint"&gt;NSURL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Given the above, we can now decode some JSON:&lt;/p&gt;

&lt;pre&gt;&lt;code class="prettyprint"&gt;do {
    let response = try BandResponse.decodeValue(bandJSON)
    print(response?.objects.first?.name) // Beatles
} catch {
    print(error)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If the JSON is valid, you’ll have a &lt;code class="prettyprint"&gt;BandResponse&lt;/code&gt; representation, and if not, &lt;code class="prettyprint"&gt;error&lt;/code&gt; will contain information on the first failure. &lt;/p&gt;
&lt;h3 id="a-generic-response-wrapper_3"&gt;&lt;a class="head_anchor" href="#a-generic-response-wrapper_3"&gt;&amp;nbsp;&lt;/a&gt;A generic Response wrapper&lt;/h3&gt;
&lt;p&gt;We can improve upon our BandResponse struct by using generics. We define a &lt;code class="prettyprint"&gt;struct&lt;/code&gt; &lt;code class="prettyprint"&gt;Response&lt;/code&gt; which is generic over &lt;code class="prettyprint"&gt;Decodable&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class="prettyprint"&gt;struct Response&amp;lt;T: Decodable&amp;gt; {
    let objects: [T]
    let lastUpdated: NSDate?
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and implement &lt;code class="prettyprint"&gt;Decodable&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class="prettyprint"&gt;extension Response: Decodable {
    static func decode&amp;lt;T: Decodable&amp;gt;(e: Extractor) throws -&amp;gt; Response&amp;lt;T&amp;gt; {
        return try Response&amp;lt;T&amp;gt;(objects: e &amp;lt;|| &amp;quot;objects&amp;quot;,
            lastUpdated: DateTimeTransformer.apply(e &amp;lt;|? &amp;quot;last_updated&amp;quot;)
        )
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we can decode the JSON to our generic collection:&lt;/p&gt;

&lt;pre&gt;&lt;code class="prettyprint"&gt;do {
    let response = try Response&amp;lt;Band&amp;gt;.decodeValue(bandJSON)
    print(response?.objects.first?.name) // Beatles
} catch {
    print(error)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And we’re done!&lt;/p&gt;

&lt;p&gt;Whether you’re building an app or an API wrapper, I recommend trying Himotoki for your next project. You can even clone my Playground from &lt;a href="https://github.com/dcaunt/himotoki-playground"&gt;GitHub&lt;/a&gt; and have a play with your own models and JSON.&lt;/p&gt;
</content>
  </entry>
</feed>
