| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
En | 中文
struct TestExCodable: ExAutoCodable {
@ExCodable private(set)
var int: Int = 0
@ExCodable("nested.nested.string", "string", "str", "s") private(set)
var string: String? = nil
}TODO:
ExCodable requires declaring properties with var and provide default values.
struct TestStruct: ExAutoCodable {
@ExCodable private(set)
var int: Int = 0
@ExCodable("string") private(set)
var string: String? = nil
}struct TestAlternativeKeys: ExAutoCodable {
@ExCodable("string", "str", "s") private(set)
var string: String! = nil
}struct TestNestedKeys: ExAutoCodable {
@ExCodable("nested.nested.string") private(set)
var string: String! = nil
}enum TestEnum: Int, Codable {
case zero = 0, one = 1
}
struct TestStructWithEnum: ExAutoCodable {
@ExCodable("enum") private(set)
var `enum` = TestEnum.zero
}struct TestManualEncodeDecode: ExAutoCodable {
@ExCodable(encode: { encoder, value in
encoder["int"] = value <= 0 ? 0 : value
}, decode: { decoder in
if let int: Int = decoder["int"], int > 0 {
return int
}
return 0
}) private(set)
var int: Int = 0
}ExCodable builtin type conversions:
Custom type conversions for specific properties:
struct TestCustomEncodeDecode: ExAutoCodable {
@ExCodable(decode: { decoder in
if let string: String = decoder["string"] {
return string.count
}
return 0
}) private(set)
var int: Int = 0
}Custom type conversions for specific model:
struct TestCustomTypeConverter: ExAutoCodable {
@ExCodable private(set)
var doubleFromBool: Double? = nil
@ExCodable private(set)
var floatFromBool: Double? = nil
}
extension TestCustomTypeConverter: ExCodableDecodingTypeConverter {
public static func decode<T: Decodable, K: CodingKey>(_ container: KeyedDecodingContainer<K>, codingKey: K, as type: T.Type) -> T? {
// for nested optionals, e.g. `var int: Int??? = nil`
let wrappedType = T?.wrappedType
// decode Double from Bool
if type is Double.Type || wrappedType is Double.Type {
if let bool = try? container.decodeIfPresent(Bool.self, forKey: codingKey) {
return (bool ? 1.0 : 0.0) as? T
}
}
// decode Float from Bool
else if type is Float.Type || wrappedType is Float.Type {
if let bool = try? container.decodeIfPresent(Bool.self, forKey: codingKey) {
return (bool ? 1.0 : 0.0) as? T
}
}
return nil
}
}Custom type conversions for global:
struct TestCustomGlobalTypeConverter: ExAutoCodable, Equatable {
@ExCodable("boolFromDouble") private(set)
var boolFromDouble: Bool? = nil
}
extension ExCodableGlobalDecodingTypeConverter: ExCodableDecodingTypeConverter {
public static func decode<T: Decodable, _K: CodingKey>(_ container: KeyedDecodingContainer<_K>, codingKey: _K, as type: T.Type) -> T? {
// for nested optionals, e.g. `var int: Int??? = nil`
let wrappedType = T?.wrappedType
// decode Bool from Double
if type is Bool.Type || wrappedType is Bool.Type {
if let double = try? container.decodeIfPresent(Double.self, forKey: codingKey) {
return (double != 0) as? T
}
}
return nil
}
}A type without ExCodable:
struct TestManualEncodingDecoding {
let int: Int
let string: String
}Manual encoding/decoding using subscripts:
extension TestManualEncodingDecoding: Codable {
enum Keys: CodingKey {
case int, string
}
init(from decoder: Decoder) throws {
int = decoder[Keys.int] ?? 0
string = decoder[Keys.string] ?? ""
}
func encode(to encoder: Encoder) throws {
encoder[Keys.int] = int
encoder[Keys.string] = string
}
}While encoding/decoding, ExCodable ignores the keyNotFound, valueNotFound, invalidValue and typeMismatch errors and return nil by default, only throws JSON errors.
ExCodable also supports throw errors:
struct TestNonnullAndThrows: ExAutoCodable {
@ExCodable(nonnull: true, throws: true) private(set)
var int: Int! = 0
}class TestClass: ExAutoCodable {
@ExCodable private(set)
var int: Int = 0
@ExCodable private(set)
var string: String? = nil
required init() {}
init(int: Int, string: String?) {
(self.int, self.string) = (int, string)
}
}class TestSubclass: TestClass {
@ExCodable private(set)
var bool: Bool = false
required init() { super.init() }
required init(int: Int, string: String, bool: Bool) {
self.bool = bool
super.init(int: int, string: string)
}
}struct TestStruct: ExAutoCodable, Equatable {
@ExCodable private(set)
var int: Int = 0
@ExCodable private(set)
var string: String? = nil
}
let json = Data(#"{"int":200,"string":"OK"}"#.utf8)
let model = try? TestStruct.decoded(from: json)
let dict = try? model.encoded() as [String: Any]
let copy = try? dict.decoded() as TestStructSee the tests for more examples.
Swift Package Manager:
.package(url: "https://github.com/ExCodable/ExCodable", from: "1.0.0")CocoaPods:
pod 'ExCodable', '~> 1.0.0'When you update to ExCodable 1.0.
Step 1: Update your code to use the old API - DEPRECATED but quick.
struct TestExCodable {
private(set) var int: Int = 0
private(set) var string: String?
}
extension TestExCodable: ExCodableDEPRECATED {
static let keyMapping: [KeyMap<Self>] = [
KeyMap(\.int, to: "int"),
KeyMap(\.string, to: "nested.nested.string", "string", "str", "s")
]
init(from decoder: Decoder) throws {
try decode(from: decoder, with: Self.keyMapping)
}
}Step 2: Upgrade your models to the new API one by one - SUGGESTED:
struct TestExCodable: ExAutoCodable {
@ExCodable private(set)
var int: Int = 0
@ExCodable("nested.nested.string", "string", "str", "s") private(set)
var string: String?
}Hope ExCodable will help you! Make a star ⭐️ 🤩
ExCodable is released under the MIT license. See LICENSE for details.
| Back | FazBrowse Home | New Git URL |