github "tattn/MoreCodable"
pod 'MoreCodable'
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)
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)
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)
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")
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
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
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)
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")
let json = """ { "date": "2019年05月27日", "dateTime": "2019年05月27日T17:26:59+0000", "timestamp": 1558978068, "timestampMilliseconds": 1558978141863, "custom": "1558978068" } """.data(using: .utf8)! struct Document: Codable { var date: Date var dateTime: Date var timestamp: Date var timestampMilliseconds: Date var custom: Date } extension Document: MultiDateFormat { static var dateFormatter: DateFormatter = { let formatter = DateFormatter() formatter.timeZone = TimeZone(identifier: "UTC") formatter.dateFormat = "yyyy.MM.dd" return formatter }() static func dateFormat(for codingKey: CodingKey) -> DateFormat? { switch codingKey { case CodingKeys.date: return .formatted(dateFormatter) case CodingKeys.dateTime: return .iso8601 case CodingKeys.timestamp: return .secondsSince1970 case CodingKeys.timestampMilliseconds: return .millisecondsSince1970 case CodingKeys.custom: return .custom({ (date, encoder) in var container = encoder.singleValueContainer() try container.encode(String(date.timeIntervalSince1970)) }, { (decoder) -> Date in let container = try decoder.singleValueContainer() let string = try container.decode(String.self) let timeInterval = TimeInterval(string)! return Date(timeIntervalSince1970: timeInterval) }) default: return nil } } } let decoded = try! MoreJSONDecoder().decode(Document.self, from: json) let encoded = try! MoreJSONEncoder().encode(document)
struct User: Codable, Hashable { // conform to Hashable let id: Int let name: String } let encoder = DictionaryCachableEncoder() let user = User(id: 123, name: "tattn") let dictionary: [String: Any] = try! encoder.encode(user) // => {"id": 123, "name": "tattn"} try! encoder.encode(user) // use the previous encoded result for the second time
- XMLDecoder/XMLEncoder
- CSVDecoder/CSVEncoder
DataConvertible
https://github.com/tattn/DataConvertible
- Fork it!
- Create your feature branch:
git checkout -b my-new-feature - Commit your changes:
git commit -am 'Add some feature' - Push to the branch:
git push origin my-new-feature - Submit a pull request :D
Donating to help me continue working on this project.
MoreCodable is released under the MIT license. See LICENSE for details.