Skip to content
MoreCodable expands the possibilities of `Codable`.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
MoreCodable.xcodeproj
Sources
Tests
.gitignore
.swift-version Update podspec Apr 8, 2019
.travis.yml
LICENSE
MoreCodable.podspec
Package.swift
README.md Update README Apr 8, 2019

README.md

MoreCodable

MoreCodable expands the possibilities of "Codable".

Installation

Carthage

github "tattn/MoreCodable"

CocoaPods

pod 'MoreCodable'

Feature

DictionaryEncoder / DictionaryDecoder

struct User: Codable {
    let id: Int
    let name: String
}

let encoder = DictionaryEncoder()
let user = User(id: 123, name: "tattn")
let dictionary: [String: Any] = try! encoder.encode(user) // => {"id": 123, "name": "tattn"}
let decoder = DictionaryDecoder()
let user = try decoder.decode(User.self, from: dictionary)

URLQueryItemsEncoder / URLQueryItemsDecoder

struct Parameter: Codable {
    let query: String
    let offset: Int
    let limit: Int
}
let parameter = Parameter(query: "ねこ", offset: 10, limit: 20)
let encoder = URLQueryItemsEncoder()
let params: [URLQueryItem] = try! encoder.encode(parameter)

var components = URLComponents(string: "https://example.com")
components?.queryItems = params
components?.url // https://example.com?query=%E3%81%AD%E3%81%93&offset=10&limit=20
let decoder = URLQueryItemsDecoder()
let parameter = try decoder.decode(Parameter.self, from: params)

ObjectMerger

struct APIResponse: Encodable {
    let id: Int
    let title: String
    let foo: String
}

struct APIResponse2: Encodable {
    let tags: [String]
}

struct Model: Decodable {
    let id: Int
    let title: String
    let tags: [String]
}

let response = APIResponse(id: 0, title: "Awesome article", foo: "bar")
let response2 = APIResponse2(tags: ["swift", "ios", "macos"])
let model = try ObjectMerger().merge(Model.self, response, response2)

// success
XCTAssertEqual(model.id, response.id)
XCTAssertEqual(model.title, response.title)
XCTAssertEqual(model.tags, response2.tags)

RuleBasedCodingKey

struct User: Codable {
    let userId: String
    let name: String

    enum CodingKeys: String, RuleBasedCodingKey {
        case userId
        case name

        func codingKeyRule(key: String) -> String {
            return key.uppercased() // custom rule
        }
    }
}

let json = """
{"USERID": "abc", "NAME": "tattn"}
""".data(using: .utf8)!

let user = try! JSONDecoder().decode(User.self, from: json) // => User(userId: "abc", name: "tattn")

SnakeCaseCodingKey

struct User: Codable {
    let userId: String
    let name: String

    enum CodingKeys: String, SnakeCaseCodingKey {
        case userId
        case name
    }
}

let json = """
{"user_id": "abc", "name": "tattn"}
""".data(using: .utf8)!

let user = try! JSONDecoder().decode(User.self, from: json) // ok

UpperCamelCaseCodingKey

struct User: Codable {
    let userId: String
    let name: String

    enum CodingKeys: String, UpperCamelCaseCodingKey {
        case userId
        case name
    }
}

let json = """
{"UserId": "abc", "Name": "tattn"}
""".data(using: .utf8)!

let user = try! JSONDecoder().decode(User.self, from: json) // ok

Failable

let json = """
[
    {"name": "Taro", "age": 20},
    {"name": "Hanako"}
]
""".data(using: .utf8)! // Hanako has no "age"

struct User: Codable {
    let name: String
    let age: Int
}

let users = try! JSONDecoder().decode([Failable<User>].self,
                                      from: json)

// success
XCTAssertEqual(users[0].value?.name, "Taro")
XCTAssertEqual(users[0].value?.age, 20)
XCTAssertNil(users[1].value)

StringTo

let json = """
{
    "int": "100",
    "articleId": "abc"
}
""".data(using: .utf8)!

struct Root: Codable {
    let int: StringTo<Int>
    let articleId: StringTo<ArticleId>

    struct ArticleId: LosslessStringConvertible, Codable {
        var description: String

        init?(_ description: String) {
            self.description = description
        }
    }
}

let root = try! JSONDecoder().decode(Root.self, from: json)

// success
XCTAssertEqual(root.int.value, 100)
XCTAssertEqual(root.articleId.value.description, "abc")

ToDo

  • XMLDecoder/XMLEncoder
  • CSVDecoder/CSVEncoder

Related project

DataConvertible
https://github.com/tattn/DataConvertible

Contributing

  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Submit a pull request :D

Support this project

Donating to help me continue working on this project.

Donate

License

MoreCodable is released under the MIT license. See LICENSE for details.

You can’t perform that action at this time.