'How to save a color in NSUserDefaults in swift?

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 !



Solution 1:[1]

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)
    }
}

Solution 2:[2]

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];

Solution 3:[3]

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)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Jaimesh Patel
Solution 3 Paul B