MoreCodable expands the possibilities of `Codable`.
Switch branches/tags
Clone or download
Latest commit d1eb167 Sep 20, 2018

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

License

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