[Swift] Convert custom class to NSData

It's necessary to convert custom object to NSData when using NSUserDefaults or NSKeyedArchiver. Furthermore, a dictionary or an array with custom class.

Here shows steps to do it.

1. Define your class
class Book: NSObject, NSCoding {
    var id:Int
    var name:String?
    var author:String?
    
    private static let KeyId = "key_id"
    private static let KeyName = "key_name"
    private static let KeyAuthor = "key_author"
    
    init(id: Int){
        self.id = id
    }
    
    required init? (coder aDecoder: NSCoder){
        self.id = aDecoder.decodeIntegerForKey(Book.KeyId)
        self.name = aDecoder.decodeObjectForKey(Book.KeyName) as? String
        self.author = aDecoder.decodeObjectForKey(Book.KeyAuthor) as? String
    }
    
    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeInteger(id, forKey: Book.KeyId)
        aCoder.encodeObject(name, forKey: Book.KeyName)
        aCoder.encodeObject(author, forKey: Book.KeyAuthor)
    }
}

You must extend your class from NSObject and implement the NSCoding protocal. Thus, you get init(coder:) and encodeWithCoder(aCode:)

2. Save data
let book = Book(id: 1)
book.name = "The first book"
book.author = "IMLC.ME"

let book2 = Book(id:2)
book.name = "The second book"
book.author = "IMLC.ME"

let books = [book, book2]

let ud = NSUserDefaults.standardUserDefaults()
ud.setObject(NSKeyedArchiver.archivedDataWithRootObject(book), forKey: "book")
ud.setObject(NSKeyedArchiver.archivedDataWithRootObject(book), forKey: "book-array")

The code above shows how to save book and books (an array) into NSUserDefaults.

3. Restore data
if let bookData = ud.objectForKey("book") as? NSData,
    let bookArrayData = ud.objectForKey("book-array") as? NSData{
    let restoredBook = NSKeyedUnarchiver.unarchiveObjectWithData(bookData) as? Book
    let restoredBookArray = NSKeyedUnarchiver.unarchiveObjectWithData(bookArrayData) as? [Book]
    
    print("Restored book \(restoredBook.name!) and book array [\(restoredBookArray[0].name!),\(restoredBookArray[1].name!)]")
}

Saving and loading data with swift dictionary is very similar to array, I wouldn't give an another sample here.

TAG: Swift, NSData, Convert, Custom class