TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

Resolved colors and SwiftData

Forums > SwiftUI

How can I leverage the color resolving feature described here: https://www.hackingwithswift.com/quick-start/swiftui/how-to-read-the-red-green-and-blue-values-from-a-color in order to save a color using SwiftData? Or would this not be the way to go about and should I try to make Color conform to Codable some other way?

2      

I've been musing the same thing. In theory, we should be able to use the new Color.Resolved type, which conforms to Codable, as the internal data representation.

So if we have an attribute called resolvedColor of type Color.Resolved, we could easily get that value out as a Color with a computed property:

var color: Color { Color(resolvedColor) }

The difficulty is setting it – resolving a color requires access to the current view's environment, which our SwiftData objects won't have. So I couldn't do something like this:

var color: Color {
  get { Color(resolvedColor) }
  set { resolvedColor = newValue.resolve(in: <# EnvironmentValues #>) }
}

2      

Probably an obvious solution at this point, but, in case the color is not being resolved in context of a View, you could use "empty" EnvironmentValues like so:

let resolvedColor = color.resolve(in: EnvironmentValues())

I'm not sure what sort of input could be taken from the Environment, perhaps color space or some adjustments related to color scheme.

I should add, however, that, whenever I tried using Color.Resolved with SwiftData, so far, it invariably ended up with a crash with this description:

AppName crashed due to fatalError in ModelCoders.swift at line 124.

Composite Coder only supports Keyed Container

This leads me to assume that SwiftData can't, currently, deal with the way Color.Resolved encodes itself. In other words, you can use the convenience of Color.Resolved to resolve colors (sounds like a totology :)) but not to store it in a SwiftData model. Here's a helper struct I ended up using with my @Model:

struct ColorComponents: Codable {
    let red: Float
    let green: Float
    let blue: Float

    var color: Color {
        Color(red: Double(red), green: Double(green), blue: Double(blue))
    }

    static func fromColor(_ color: Color) -> ColorComponents {
        let resolved = color.resolve(in: EnvironmentValues())
        return ColorComponents(
            red: resolved.red,
            green: resolved.green,
            blue: resolved.blue
        )
    }
}

3      

Hacking with Swift is sponsored by RevenueCat.

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.