In my App for macOS and iOS I use colors created from here: https://uiwjs.github.io/ui-color/ and then f.e. Works fine.
Color(red: 1.47, green: 1.9, blue: 2.3).opacity(1)
However, for some colors I want them saved in UserDefaults and read/write by UserDefaults.standard
methods and read/write by @AppStorage
.
I did try to use, but this gives me runtime errors.
static let infoListRowReadBGColor = Color(red: 2.55, green: 1.71, blue: 1.07).opacity(1)
static let infoListRowUnReadBGColor = Color(red: 2.55, green: 2.12, blue: 1.38).opacity(1)
var defaults = UserDefaults.standard
defaults.setValue(InAppDefaults.infoListRowReadBGColor, forKey: "infoListRowReadBGColor")
defaults.setValue(InAppDefaults.infoListRowUnReadBGColor, forKey: "infoListRowUnReadBGColor")
What do I need to change to get this working, read and write, using UserDefaults.standard
and @AppStorage
? I did try the extension methode from a posting around here, but I guess I did something very wrong, because it doesn't work with @AppStorage
.
Using Xcode 13 and 14 for dev result for macOS 12 and iOS 15.
You can't by default store Color() in UserDefaults, but you can use @AppStorage and NSKeyedArchiver to achieve this result. The full example and documentation are provided in this article.
Create an extension:
import SwiftUI
import UIKit
extension Color: RawRepresentable {
public init?(rawValue: String) {
guard let data = Data(base64Encoded: rawValue) else {
self = .black
return
}
do {
if let color = try NSKeyedUnarchiver.unarchivedObject(ofClass: UIColor.self, from: data) {
self = Color(color)
} else {
self = .black
}
} catch {
self = .black
}
}
public var rawValue: String {
do {
let data = try NSKeyedArchiver.archivedData(withRootObject: UIColor(self), requiringSecureCoding: false) as Data
return data.base64EncodedString()
} catch {
return ""
}
}
}
And use it as such:
@AppStorage("colorkey") var storedColor: Color = .black
var body: some View {
VStack {
ColorPicker("Persisted Color Picker", selection: $storedColor, supportsOpacity: true)
}
}