Saving custom Swift class with NSCoding to UserDefaults

Georg picture Georg · Oct 20, 2014 · Viewed 56.1k times · Source

I am currently trying to save a custom Swift class to NSUserDefaults. Here is the code from my Playground:

import Foundation

class Blog : NSObject, NSCoding {

    var blogName: String?

    override init() {}

    required init(coder aDecoder: NSCoder) {
        if let blogName = aDecoder.decodeObjectForKey("blogName") as? String {
            self.blogName = blogName
        }
    }

    func encodeWithCoder(aCoder: NSCoder) {
        if let blogName = self.blogName {
            aCoder.encodeObject(blogName, forKey: "blogName")
        }
    }

}

var blog = Blog()
blog.blogName = "My Blog"

let ud = NSUserDefaults.standardUserDefaults()    
ud.setObject(blog, forKey: "blog")

When I run the code, I get the following error

Execution was interrupted, reason: signal SIGABRT.

in the last line (ud.setObject...)

The same code also crashes when in an app with the message

"Property list invalid for format: 200 (property lists cannot contain objects of type 'CFType')"

Can anybody help? I am using Xcode 6.0.1 on Maverick. Thanks.

Answer

Ghulam Rasool picture Ghulam Rasool · Mar 27, 2018

In Swift 4 or higher, Use Codable.

In your case, use following code.

class Blog: Codable {
   var blogName: String?
}

Now create its object. For example:

var blog = Blog()
blog.blogName = "My Blog"

Now encode it like this:

if let encoded = try? JSONEncoder().encode(blog) {
    UserDefaults.standard.set(encoded, forKey: "blog")
}

and decode it like this:

if let blogData = UserDefaults.standard.data(forKey: "blog"),
    let blog = try? JSONDecoder().decode(Blog.self, from: blogData) {
}