Codable
Codable
Tool
Quickly type JSON structs for Swift or any other languages. Network Models
https://app.quicktype.io/
UserDefaults
Codable Property Wrapper
On iOS 12 and prior, primitive types (Int, Double, Bool, etc), while Codable
as a property of a Codable type, cannot itself be JSON encodable. Trying encoding/decoding with these types on iOS 12 earlier platforms will throw an error.
To remedy this behavior we wrap the Codable value in a simple Codable struct.
User Defaults example usage
@propertyWrapper
public struct UserDefaultsBacked<Value: Codable> {
private let key: String
private let defaultValue: Value
private let domain: UserDefaults
public var wrappedValue: Value { }
public init(key: String, defaultValue: Value, domain: UserDefaults = .standard) {
self.key = key
self.defaultValue = defaultValue
self.domain = domain
}
struct Wrapper<Value>: Codable where Value: Codable {
let value: Value
}
// Wrapped value
// GET
do {
let wrappedValue = try JSONDecoder().decode(Wrapper<Value>.self, from: data)
return wrappedValue.value
}
// SET
set {
do {
let data = try JSONEncoder().encode(Wrapper(value: newValue))
domain.setValue(data, forKey: key)
} catch {}
}
Decoder
Snake case issue
ERROR: keyNotFound(CodingKeys(stringValue: "iso_3166_1", intValue: nil)
Just use
.convertFromSnakeCase
for decoder strategy
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
SO | swiftui-get-error-when-decoding-json-data-which-includes-key-name-as-iso
The data couldn’t be read because it isn’t in the correct format.
dataCorrupted(Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "", intValue: 0), CodingKeys(stringValue: "TestKey", intValue: nil)], debugDescription: "Cannot initialize TestKey from invalid String value TestValue", underlyingError: nil))
This probably happen because the API changed few things on their backend and you should have had optional initializers rather than concrete tie-ins. this resulted in full failure from the client consumer side of things and it led to your app / software in broken state. Very bad design but I was working around a POC and I just wanted to build something quickly.
Troubleshooting coding / decoding errors
When using JSONDecoder
or .decode()
functions, make sure you have do try catch added explicitly so that it doesn't fail silently with those JSON coding / decoding views.
Make sure to use String(describing:)
as well instead of .localizedDescriptions
do {
let decoded = try JSONDecoder().decode([Struct].self, from: data!)
} catch {
// print(error.localizedDescription) // <- ⚠️ Don't use this!
print(String(describing: error)) // <- ✅ Use this for debuging!
}