How to save a color in NSUserDefaults in swift?
Asked Answered
P

4

6

I have a litle problem with saving a color in NSUserDefaults . In objective-c is easy :

-(NSColor *)colorForKey:(NSString *)key{
NSData  *data;
NSColor *color;
data = [[NSUserDefaults standardUserDefaults] objectForKey:key];
color= [NSUnarchiver unarchiveObjectWithData:data];
if( ! [color isKindOfClass:[NSColor class]] ){
    color = nil;
}
return color;
}

-(void)setColor:(NSColor *)color forKey:(NSString *)key{
    NSData *data = [NSArchiver archivedDataWithRootObject:color];
    [[NSUserDefaults standardUserDefaults] setObject:data forKey:key];
}

The above code works fine in objective-c, but when i try to write same code in swift, I receive errors at reading color from NSUserDefaults.

 func saveColorForKey (color:NSColor , key:NSString ) {

    var data:NSData = NSData()
    data = NSArchiver.archivedDataWithRootObject(color)
    NSUserDefaults.standardUserDefaults().setObject(data, forKey: key)
}
func colorForKey(key:NSString) -> NSColor{
    var  data: AnyObject? = NSUserDefaults.standardUserDefaults().objectForKey(key)
    var color: AnyObject? =  NSUnarchiver.unarchiveObjectWithData(data? as NSData)

    return color as NSColor
}

Thanks , and sorry for my english !

Plumbo answered 20/10, 2014 at 11:15 Comment(1)
place tick if my answer is true so that in future this will help others. thanksObeded
O
16

For Objective C

place like this.

NSData *colorData = [NSKeyedArchiver archivedDataWithRootObject:color];
[[NSUserDefaults standardUserDefaults] setObject:colorData forKey:@"myColor"];

To get back like this.

NSData *colorData = [[NSUserDefaults standardUserDefaults] objectForKey:@"myColor"];
UIColor *color = [NSKeyedUnarchiver unarchiveObjectWithData:colorData];

For Swift

set like this

 var userSelectedColor : NSData? = (NSUserDefaults.standardUserDefaults().objectForKey("UserSelectedColor") as? NSData)

if (userSelectedColor != nil) {
    var colorToSetAsDefault : UIColor = UIColor.redColor()
    var data : NSData = NSKeyedArchiver.archivedDataWithRootObject(colorToSetAsDefault)
    NSUserDefaults.standardUserDefaults().setObject(data, forKey: "UserSelectedColor")
    NSUserDefaults.standardUserDefaults().synchronize()
    println("SET DEFAULT USER COLOR TO RED")
}

get like this.

if let userSelectedColorData = NSUserDefaults.standardUserDefaults().objectForKey("UserSelectedColor") as? NSData {
    if let userSelectedColor = NSKeyedUnarchiver.unarchiveObjectWithData(userSelectedColorData) as? UIColor {
        println(userSelectedColor)
    }
}

For Swift 4.2

place like this.

let colorToSetAsDefault : UIColor = UIColor.red
let data : Data = NSKeyedArchiver.archivedData(withRootObject: colorToSetAsDefault) as Data
UserDefaults.standard.set(data, forKey: "UserSelectedColor")
UserDefaults.standard.synchronize()
print("SET DEFAULT USER COLOR TO RED")

To get back like this.

if let userSelectedColorData = UserDefaults.standard.object(forKey: "UserSelectedColor") as? Data {
    if let userSelectedColor = NSKeyedUnarchiver.unarchiveObject(with:userSelectedColorData as Data) as? UIColor {
        print(userSelectedColor)
    }
}
Obeded answered 20/10, 2014 at 11:19 Comment(1)
That is Objective-C. The question was how to implement it in Swift.Blagoveshchensk
T
0

Storing an NSColor instance in user defaults

store the value in aColor in user defaults as the value for key aKey

NSData *theData=[NSArchiver archivedDataWithRootObject:aColor]; [[NSUserDefaults standardUserDefaults] setObject:theData forKey:aKey];

Tunstall answered 20/10, 2014 at 12:14 Comment(0)
T
0

This is a slightly modernised version of using NSKeyedArchiver and NSKeyedUnarchiver to store a NSColor in UserDefaults, as a value property:

var backgroundColor: NSColor {
    get {
        if let data = UserDefaults.standard.data(forKey: #function),
           let color = try? NSKeyedUnarchiver.unarchivedObject(ofClass: NSColor.self, from: data) {
            return color
        }
        return .windowBackgroundColor // or any other default color
    }
    set {
        if let data = try? NSKeyedArchiver.archivedData(withRootObject: newValue, requiringSecureCoding: false) {
            UserDefaults.standard.set(data, forKey: #function)
        }
    }
}
Telephotography answered 14/7 at 22:26 Comment(0)
U
-1

You can use a property wrapper to create auto stored property in UserDefaults.

@propertyWrapper
struct ColorStorage {

    private let key: String

    init(key: String) {
        self.key = key
    }

    var wrappedValue: UIColor {
        get {
            guard let data = UserDefaults.standard.data(forKey: key),
            let components = try? JSONDecoder().decode([CGFloat].self, from: data)
            else { return UIColor.label }
            
            return UIColor(red: components[0], green: components[1], blue: components[2], alpha: components[3])
        }
        set {
            var r, g, b, a: CGFloat
            (r, g, b, a) = (0, 0, 0, 0)
            let data = try? JSONEncoder().encode([r, g, b, a])
            UserDefaults.standard.set(data, forKey: key)
        }
    }
}

Usage:

struct Settings {
    @ColorStorage(key: "primaryColor")
    static var primaryColor: UIColor
}

Settings.primaryColor = .green
print(Settings.primaryColor)
Underwing answered 20/4, 2022 at 10:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.