Saving custom Swift class with NSCoding to UserDefaults
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) {}
The first problem is you have to ensure that you have a non-mangled class name:
@objc(Blog)class Blog : NSObject, NSCoding {
Then you have to encode the object (into an NSData) before you can store it into the user defaults:
ud.setObject(NSKeyedArchiver.archivedDataWithRootObject(blog), forKey: "blog")
Similarly, to restore the object you'll need to unarchive it:
if let data = ud.objectForKey("blog") as? NSData { let unarc = NSKeyedUnarchiver(forReadingWithData: data) unarc.setClass(Blog.self, forClassName: "Blog") let blog = unarc.decodeObjectForKey("root")}
Note that if you're not using it in the playground it's a little simpler as you don't have to register the class by hand:
if let data = ud.objectForKey("blog") as? NSData { let blog = NSKeyedUnarchiver.unarchiveObjectWithData(data)}
As @dan-beaulieu suggested I answer my own question:
Here is the working code now:
Note: Demangling of the class name was not necessary for the code to work in Playgrounds.
import Foundationclass 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") } }}let ud = NSUserDefaults.standardUserDefaults()var blog = Blog()blog.blogName = "My Blog"ud.setObject(NSKeyedArchiver.archivedDataWithRootObject(blog), forKey: "blog")if let data = ud.objectForKey("blog") as? NSData { let unarc = NSKeyedUnarchiver(forReadingWithData: data) let newBlog = unarc.decodeObjectForKey("root") as Blog}