Serializing SwiftUI Color

There are plenty of resources out there that will tell you how to make SwiftUI’s Color conform to the Codable protocol. They all boil down to creating a UIColor (when you’re running on iOS) or NSColor (when you’re running on macOS) and then grabbing the color components from there, because SwiftUI is helpful by not letting you access those things directly. The thing I learned yesterday is that if you construct your SwiftUI Color from a color asset catalog and then you construct an NSColor out of it, you need to set a color space before you can grab the components. If you don’t do that, then the thread that’s doing the work will crash. So, the code needs to look like this:

import SwiftUI

#if canImport(UIKit)
import UIKit
#elseif canImport(AppKit)
import AppKit

extension Color {
    // swiftlint:disable:next large_tuple
    var components: (red: Double, green: Double, blue: Double, opacity: Double) {

        #if canImport(UIKit)
        typealias NativeColor = UIColor
        #elseif canImport(AppKit)
        typealias NativeColor = NSColor

        var red: CGFloat = 0
        var green: CGFloat = 0
        var blue: CGFloat = 0
        var opacity: CGFloat = 0

        var native = NativeColor(self)

        #if canImport(AppKit)
        native = native.usingColorSpace(NSColorSpace.genericRGB)!

        native.getRed(&red, green: &green, blue: &blue, alpha: &opacity)

        return (red, green, blue, opacity)

Published by pirateguillermo

I play the bagpipes. I program computers. I support my family in their various endeavors, and I enjoy my wonderful life.

One thought on “Serializing SwiftUI Color

  1. I have hated the way *Color works since .. well, the early 90’s at least. The reason for them being so complicated is that they are really complicated – if you give a shit. I have always wanted
    [[CloseEnoughColor red: ###, green: ###, blue: ###] set]
    to do what I obviously want without all the hassle of dealing with color spaces and all that mumbojumbo that I don’t give a crap about because I’m not publishing this and I just need it to show up as purple-ish.

Leave a ReplyCancel reply