Himotoki (紐解き) is a type-safe JSON decoding library written purely in Swift. This library is highly inspired by the popular Swift JSON parsing libraries: Argo and ObjectMapper.
Himotoki has the same meaning of 'decoding' in Japanese.
- Just do JSON decoding (deserialization) well. JSON encoding (serialization) will not be supported going forward. 😉
- Much simpler API.
- Fail-fast conditional model building. This is useful for some
structs with non-optionalletproperties. - No external dependencies.
Let's take a look at a simple example:
struct Group: Himotoki.Decodable { let name: String let floor: Int let locationName: String let optional: [String]? // MARK: Himotoki.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() } }Himotoki to Decodable (Himotoki.Decodable) to avoid type name collision with Foundation.Decodable in Xcode 9 or later.
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 -> Tpublic 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]?
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 |
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, URL> { urlString throws -> URL in if let url = URL(string: urlString) { return url } throw customError("Invalid URL string: \(urlString)") } let url: URL = try URLTransformer.apply(e <| "foo_url") let otherURLs: [URL] = try URLTransformer.apply(e <| "bar_urls")Himotoki 4.x requires / supports the following environments:
- Swift 4.2 / Xcode 10.1 or later
- OS X 10.9 or later
- iOS 8.0 or later
- tvOS 9.0 or later
- watchOS 2.0 or later
- Linux is also supported
Currently Himotoki supports installation via the package managers Carthage and CocoaPods.
Himotoki is Carthage compatible.
- Add
github "ikesyo/Himotoki" ~> 3.1to your Cartfile. - Run
carthage update.
Himotoki also can be used by CocoaPods.
-
Add the followings to your Podfile:
use_frameworks! pod "Himotoki", "~> 3.1"
-
Run
pod install.
Himotoki is released under the MIT License.