-1

Whenever I SAVE a color as shown below:

slitherColor = sender.currentTitleColor
let userDefaults3 = NSUserDefaults.standardUserDefaults()
userDefaults3.setValue(slitherColor, forKey: "SSlitherC")
userDefaults3.synchronize()

I get a SIGABRT error. When the screen first loads, this is what I used to load the non existent data which worked without bugs:

let userDefaults3 = NSUserDefaults.standardUserDefaults()
if let slitherColor2 = userDefaults.valueForKey("SSlitherC") {
    slitherColor = slitherColor2 as! UIColor
  }
    else {
    slitherColor = UIColor.yellowColor()    
  }

Any help on how to fix this bug? Also, here is the SIGABRT bug message:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object UIDeviceRGBColorSpace 0.0352708 1 0.161752 1 for key SSlitherC'
Andy Lebo
  • 64
  • 8

2 Answers2

0

UIColors can't be directly saved in NSUserDefaults because NSUserDefaults is basically a glorified way of accessing a Plist file for your app. Instead, you can archive and unarchive the colour with NSKeyedArchiver so it can be saved properly.

Change your saving code to:

slitherColor = sender.currentTitleColor
let userDefaults3 = NSUserDefaults.standardUserDefaults()
let slitherColorData = NSKeyedArchiver.archivedDataWithRootObject(slitherColor)
userDefaults3.setObject(slitherColorData, forKey: "SSlitherC")
userDefaults3.synchronize()

and the code that gets the colour to:

let userDefaults3 = NSUserDefaults.standardUserDefaults()
if let slitherColorData2 = userDefaults3.dataForKey("SSlitherC"), let slitherColor2 = NSKeyedUnarchiver.unarchiveObjectWithData(colorData) as? UIColor {
    slitherColor = slitherColor2
} else {
    slitherColor = UIColor.yellowColor()    
}
AppleBetas
  • 88
  • 6
  • (colorData) in the second part doesn't work. What do you mean? – Andy Lebo Aug 28 '16 at 22:51
  • never mind my comment above. I fixed that part. Now i"m running the code and get another SIGABRT error: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -CGColor not defined for the UIColor ; need to first convert colorspace.' This happens when I try to load the colors that I already saved.. Help Pls – Andy Lebo Aug 28 '16 at 23:08
  • By the way @Stacksza I replaced "colorData" with "archivedDataWithRootObject(slitherColor)" – Andy Lebo Aug 28 '16 at 23:11
0

You can not save UIColor directly to the NSUserDefaults, to do that you need to archive and unarchive color object and save the data. To save:

let colorData = NSKeyedArchiver.archivedDataWithRootObject(slitherColor)
userDefaults3.setObject(slitherColor, forKey: "SSlitherC")

and to get back:

if let colorData = userDefaults3.dataForKey(key) {
  let color = NSKeyedUnarchiver.unarchiveObjectWithData(colorData) as? UIColor
}

Hereis the extension on NSUserDefautls which helps to save and retrieve data. I will copy the code here in case that gist file got deleted we still have valid info.

extension NSUserDefaults {

    func colorForKey(key: String) -> UIColor? {
        var color: UIColor?
        if let colorData = dataForKey(key) {
            color = NSKeyedUnarchiver.unarchiveObjectWithData(colorData) as? UIColor
        }
        return color
    }

    func setColor(color: UIColor?, forKey key: String) {
        var colorData: NSData?
        if let color = color {
            colorData = NSKeyedArchiver.archivedDataWithRootObject(color)
        }
        setObject(colorData, forKey: key)
    }

}

you can call this method

  1. To set save color userDefaults.setColor(color: color, forKey key: key)

  2. To get color key userDefaults.colorForKey(key)

Swift 3.0:

extension UserDefaults {

func color(forKey key: String) -> UIColor? {
    var color: UIColor?
    if let colorData = data(forKey: key) {
        color = NSKeyedUnarchiver.unarchiveObject(with: colorData) as? UIColor
    }
    return color
}

func set(color: UIColor?, forKey key: String) {
    var colorData: NSData?
    if let color = color {
        colorData = NSKeyedArchiver.archivedData(withRootObject: color)
    }
    set(colorData, forKey: key)
}

}

Usage:

let userDefault = UserDefaults.standard
userDefault.set(color: color, forKey: key)
userDefault.color(forKey: key)
Adnan Aftab
  • 14,377
  • 4
  • 45
  • 54
  • Can you be more specific? (Using my data and objects in example) – Andy Lebo Aug 28 '16 at 23:32
  • You can not save all custom objects in user defaults, so for that you need to archive it to NSData and then save it as an object. I would suggest copy this exntension and use these methods, it will take care of every thing. – Adnan Aftab Aug 28 '16 at 23:40
  • @AndyLebo I have update answer for swift 3.0 as well. Copy paste extension and use the set color and color for key methods. – Adnan Aftab Aug 28 '16 at 23:47