Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ikesyo/himotoki

A type-safe JSON decoding library purely written in Swift
https://github.com/ikesyo/himotoki

decoding json swift

Last synced: 5 days ago
JSON representation

A type-safe JSON decoding library purely written in Swift

Awesome Lists containing this project

README

        

# Himotoki

[![Join the chat at https://gitter.im/ikesyo/Himotoki](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ikesyo/Himotoki?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

[![GitHub release](https://img.shields.io/github/release/ikesyo/Himotoki.svg)](https://github.com/ikesyo/Himotoki/releases)
[![CI Status](https://travis-ci.org/ikesyo/Himotoki.svg)](https://travis-ci.org/ikesyo/Himotoki)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
[![Swift Package Manager](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)](https://github.com/apple/swift-package-manager)

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](https://github.com/thoughtbot/Argo) and [ObjectMapper](https://github.com/Hearst-DD/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. :wink:
- Much simpler API.
- Fail-fast conditional model building. This is useful for some `struct`s with non-optional `let` properties.
- No external dependencies.

Let's take a look at a simple example:

```swift
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()
}
}
```

:warning: __Please note that you should need to add the module name `Himotoki` to `Decodable` (`Himotoki.Decodable`) to avoid type name collision with `Foundation.Decodable` in Xcode 9 or later.__ :warning:

## 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(_ keyPath: KeyPath) throws -> T`
- `public func valueOptional(_ keyPath: KeyPath) throws -> T?`
- `public func array(_ keyPath: KeyPath) throws -> [T]`
- `public func arrayOptional(_ keyPath: KeyPath) throws -> [T]?`
- `public func dictionary(_ keyPath: KeyPath) throws -> [String: T]`
- `public func dictionaryOptional(_ 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:

```swift
// Creates a `Transformer` instance.
let URLTransformer = Transformer { 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")
```

## Requirements

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](https://swift.org/download/#linux) is also supported

## Installation

Currently Himotoki supports installation via the package managers [Carthage](https://github.com/Carthage/Carthage) and [CocoaPods](https://cocoapods.org/).

### Carthage

Himotoki is [Carthage](https://github.com/Carthage/Carthage) compatible.

- Add `github "ikesyo/Himotoki" ~> 3.1` to your Cartfile.
- Run `carthage update`.

### CocoaPods

Himotoki also can be used by [CocoaPods](https://cocoapods.org/).

- Add the followings to your Podfile:

```ruby
use_frameworks!
pod "Himotoki", "~> 3.1"
```

- Run `pod install`.

## License

Himotoki is released under the [MIT License](LICENSE.md).