Search code examples
objective-ccocoa-touchnsuserdefaultsuicolor

Saving UIColor to and loading from NSUserDefaults


What's the easiest way to save a UIColor into NSUserDefaults and then get it back out?


Solution

  • With the accepted answer, you'll quickly end up with a lot of NSKeyed archives & unarchives all over your code. A cleaner solution is to extend UserDefaults. This is exactly what extensions are for; UserDefaults probably doesn't know about UIColor as it is because UIKit and Foundation are different frameworks.

    Swift

    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(_ value: UIColor?, forKey key: String) {
            var colorData: Data?
            if let color = value {
                colorData = NSKeyedArchiver.archivedData(withRootObject: color)
            }
            set(colorData, forKey: key)
        }
    
    }
    

    Swift 4.2

    extension UserDefaults {
    
        func color(forKey key: String) -> UIColor? {
    
            guard let colorData = data(forKey: key) else { return nil }
    
            do {
                return try NSKeyedUnarchiver.unarchivedObject(ofClass: UIColor.self, from: colorData)
            } catch let error {
                print("color error \(error.localizedDescription)")
                return nil
            }
    
        }
    
        func set(_ value: UIColor?, forKey key: String) {
    
            guard let color = value else { return }
            do {
                let data = try NSKeyedArchiver.archivedData(withRootObject: color, requiringSecureCoding: false)
                set(data, forKey: key)
            } catch let error {
                print("error color key data not saved \(error.localizedDescription)")
            }
    
        }
    
    }
    

    Usage

    UserDefaults.standard.set(UIColor.white, forKey: "white")
    let whiteColor = UserDefaults.standard.color(forKey: "white")
    

    This can also be done in Objective-C with a category.

    I've added the Swift file as a gist here.