Skip to content

Instantly share code, notes, and snippets.

@darrarski
Forked from krzyzanowskim/JSONCodable.swift
Last active July 30, 2020 10:59
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save darrarski/6a6ddbc6877f95e98e0cffc18b733d30 to your computer and use it in GitHub Desktop.
Save darrarski/6a6ddbc6877f95e98e0cffc18b733d30 to your computer and use it in GitHub Desktop.
import Foundation
public protocol JSONEncodable: Encodable {
static var keyEncodingStrategy: JSONEncoder.KeyEncodingStrategy { get }
static var dateEncodingStrategy: JSONEncoder.DateEncodingStrategy { get }
static var dataEncodingStrategy: JSONEncoder.DataEncodingStrategy { get }
static var nonConformingFloatEncodingStrategy: JSONEncoder.NonConformingFloatEncodingStrategy { get }
func toJSON() throws -> Data
}
public extension JSONEncodable {
static var keyEncodingStrategy: JSONEncoder.KeyEncodingStrategy { .convertToSnakeCase }
static var dateEncodingStrategy: JSONEncoder.DateEncodingStrategy { .iso8601 }
static var dataEncodingStrategy: JSONEncoder.DataEncodingStrategy { .base64 }
static var nonConformingFloatEncodingStrategy: JSONEncoder.NonConformingFloatEncodingStrategy { .throw }
func toJSON() throws -> Data {
let encoder = JSONEncoder()
encoder.keyEncodingStrategy = Self.keyEncodingStrategy
encoder.dateEncodingStrategy = Self.dateEncodingStrategy
encoder.dataEncodingStrategy = Self.dataEncodingStrategy
encoder.nonConformingFloatEncodingStrategy = Self.nonConformingFloatEncodingStrategy
return try encoder.encode(self)
}
}
public protocol JSONDecodable: Decodable {
static var keyDecodingStrategy: JSONDecoder.KeyDecodingStrategy { get }
static var dateDecodingStrategy: JSONDecoder.DateDecodingStrategy { get }
static var dataDecodingStrategy: JSONDecoder.DataDecodingStrategy { get }
static var nonConformingFloatDecodingStrategy: JSONDecoder.NonConformingFloatDecodingStrategy { get }
static func from(json data: Data) throws -> Self
}
public extension JSONDecodable {
static var keyDecodingStrategy: JSONDecoder.KeyDecodingStrategy { .convertFromSnakeCase }
static var dateDecodingStrategy: JSONDecoder.DateDecodingStrategy { .iso8601 }
static var dataDecodingStrategy: JSONDecoder.DataDecodingStrategy { .base64 }
static var nonConformingFloatDecodingStrategy: JSONDecoder.NonConformingFloatDecodingStrategy { .throw }
static func from(json data: Data) throws -> Self {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = Self.keyDecodingStrategy
decoder.dateDecodingStrategy = Self.dateDecodingStrategy
decoder.dataDecodingStrategy = Self.dataDecodingStrategy
decoder.nonConformingFloatDecodingStrategy = Self.nonConformingFloatDecodingStrategy
return try decoder.decode(Self.self, from: data)
}
}
public protocol JSONCodable: JSONEncodable & JSONDecodable {}
// Usage
struct Filter: JSONCodable {
let id: String
}
let filter = Filter(id: "foo")
let encodedFilter = try filter.toJSON()
let jsonString = String(data: encodedFilter, encoding: .utf8)
let decodedFilter = try Filter.from(json: encodedFilter)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment