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 the userDefaults and read/write by UserDefaults.standard methodes 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.default and @AppStore? I did try the extension methode from a posting around here, but I guess I do something very wrong, because it doesn't work with @AppStorage.
Using XCode 13 and 14 for dev result for MacOS 12 and iOS 15.
CodePudding user response:
you can try converting color into data and store the data instead.
here's a uikit version extending UIColor you can use it for SwiftUI's Color too
import UIKit
extension UIColor {
class func color(data: Data) -> UIColor {
try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as! UIColor
}
func encode() -> Data {
try! NSKeyedArchiver.archivedData(withRootObject: self, requiringSecureCoding: false)
}
}
you can persist the color using the encode function and once you retrieve the data, you can pass it on the class func to get the color
CodePudding user response:
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 is provided from this article.
Create an extension:
import Foundation
import SwiftUI
import UIKit
extension Color: RawRepresentable {
public init?(rawValue: String) {
guard let data = Data(base64Encoded: rawValue) else{
self = .black
return
}
do{
let color = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? UIColor ?? .black
self = Color(color)
}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)
}
}