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

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.


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"}