A type-safe JSON decoding library purely written in Swift
Swift Ruby Objective-C
Latest commit 1a03ab5 Feb 11, 2017 @ikesyo committed on GitHub Merge pull request #165 from ikesyo/deprecate-keypath-nil-literal
[KeyPath] Deprecate ExpressibleByNilLiteral conformance

README.md

Himotoki

Join the chat at https://gitter.im/ikesyo/Himotoki

GitHub release CI Status Carthage compatible Swift Package Manager

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.

Himotoki has the same meaning of 'decoding' in Japanese.

  • Just do JSON decoding (deserialization) well. JSON encoding (serialization) would not be supported going forward. 😉
  • Much simpler API.
  • Fail-fast conditional model building. This is useful for some structs with non-optional let properties.
  • No external dependencies.

See a simple example from a test code:

struct Group: Decodable {
    let name: String
    let floor: Int
    let locationName: String
    let optional: [String]?

    // MARK: Decodable

    static func decode(_ e: Extractor) throws -> Group {
        return try Group(
            name: e <| "name",
            floor: e <| "floor",
            locationName: e <| [ "location", "name" ], // Parse nested objects
            optional: e <||? "optional" // Parse optional arrays of values
        )
    }
}

func testGroup() {
    var JSON: [String: AnyObject] = [ "name": "Himotoki", "floor": 12 ]

    let g = try? Group.decodeValue(JSON)
    XCTAssert(g != nil)
    XCTAssert(g?.name == "Himotoki")
    XCTAssert(g?.floor == 12)
    XCTAssert(g?.optional == nil)

    JSON["name"] = nil
    do {
        try Group.decodeValue(JSON)
    } catch let DecodeError.MissingKeyPath(keyPath) {
        XCTAssert(keyPath == "name")
    } catch {
        XCTFail()
    }
}

Implementing the decode method for your models

To implement the decode method for you models conforming to the Decodable protocol, you can use the following Extractor's extraction methods:

  • public func value<T: Decodable>(_ keyPath: KeyPath) throws -> T
  • public func valueOptional<T: Decodable>(_ keyPath: KeyPath) throws -> T?
  • public func array<T: Decodable>(_ keyPath: KeyPath) throws -> [T]
  • public func arrayOptional<T: Decodable>(_ keyPath: KeyPath) throws -> [T]?
  • public func dictionary<T: Decodable>(_ keyPath: KeyPath) throws -> [String: T]
  • public func dictionaryOptional<T: Decodable>(_ keyPath: KeyPath) throws -> [String: T]?

Extraction Operators

Himotoki also supports the following operators to decode JSON elements, where T is a generic type conforming to the Decodable protocol.

Operator Decode element as Remarks
<| T A value
<|? T? An optional value
<|| [T] An array of values
<||? [T]? An optional array of values
<|-| [String: T] A dictionary of values
<|-|? [String: T]? An optional dictionary of values

Value Transformation

You can transform an extracted value to an instance of non-Decodable types by passing the value to a Transformer instance as follows:

// Creates a `Transformer` instance.
let URLTransformer = Transformer<String, NSURL> { URLString throws -> NSURL in
    if let URL = NSURL(string: URLString) {
        return URL
    }

    throw customError("Invalid URL string: \(URLString)")
}

let URL = try URLTransformer.apply(e <| "foo_url")
let otherURLs = try URLTransformer.apply(e <|| "bar_urls")

Requirements

Himotoki 3.x requires / supports the following environments:

  • Swift 3.0.1 / Xcode 8.1
    • If you use Swift 2.2 (Xcode 7.3) or Swift 2.3 (Xcode 8), you can use 2.1.1 instead.
  • OS X 10.9 or later
  • iOS 8.0 or later
  • tvOS 9.0 or later
  • watchOS 2.0 or later

Installation

There are 2 options.

Carthage

Himotoki is Carthage compatible.

  • Add github "ikesyo/Himotoki" ~> 3.0 to your Cartfile.
  • Run carthage update.

CocoaPods

Himotoki also can be used by CocoaPods.

  • Add the followings to your Podfile:

    use_frameworks!
    pod "Himotoki", "~> 3.0"
  • Run pod install.

License

Himotoki is released under the MIT License.