Codable UIColor via property wrapper
We can add Codable
support to UIColor
with the help of a property wrapper. The following property wrapper allows us to encode and decode UIColor
values as hex strings:
import UIKit
import ColorToolbox
@propertyWrapper
struct HexCodableColor: Codable {
var wrappedValue: UIColor
init(wrappedValue: UIColor) {
self.wrappedValue = wrappedValue
}
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let hexString = try container.decode(String.self)
guard let color = UIColor(hex: hexString) else {
throw DecodingError.dataCorruptedError(
in: container,
debugDescription: "The value is not a valid hex color"
)
}
wrappedValue = color
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(wrappedValue.toHex())
}
}
The property wrapper uses the init?(hex:)
and toHex()
extensions from ColorToolbox.
Usage
Apply the wrapper to a UIColor
property in a Codable
struct/class:
struct MyModel: Codable {
// ...
@HexCodableColor var color: UIColor
}
Now we can encode/decode the struct the same way we would with any other Codable
type:
let model = MyModel(color: .red)
let encoder = JSONEncoder()
let data = try encoder.encode(model) // -> {"color":"#FF0000"}