Converting custom class object into NSData
Here is one simple example for you:
//Custom class.class Person: NSObject, NSCoding { var name: String! var age: Int! required convenience init(coder decoder: NSCoder) { self.init() self.name = decoder.decodeObjectForKey("name") as! String self.age = decoder.decodeObjectForKey("age") as! Int } convenience init(name: String, age: Int) { self.init() self.name = name self.age = age } func encodeWithCoder(coder: NSCoder) { if let name = name { coder.encodeObject(name, forKey: "name") } if let age = age { coder.encodeObject(age, forKey: "age") } }}//create an instance of your custom class.var newPerson = [Person]()//add some values into custom class.newPerson.append(Person(name: "Leo", age: 45))newPerson.append(Person(name: "Dharmesh", age: 25))//store you class object into NSUserDefaults.let personData = NSKeyedArchiver.archivedDataWithRootObject(newPerson)NSUserDefaults().setObject(personData, forKey: "personData")//get your object from NSUserDefaults.if let loadedData = NSUserDefaults().dataForKey("personData") { if let loadedPerson = NSKeyedUnarchiver.unarchiveObjectWithData(loadedData) as? [Person] { loadedPerson[0].name //"Leo" loadedPerson[0].age //45 }}
Tested with playground.
Hope this helps.
This following sample code is based on Richie Rich's answer (see above) and passes tests in this environment:
Xcode version 9.1 (9B55)
Swift version 4.0.2 (swiftlang-900.0.69.2 clang-900.0.38, Target: x86_64-apple-macosx10.9)
MacBook Air (11-inch, Mid 2012) with macOS High Sierra (version 10.13.1)
// Foundation is required to NSObject and NSCodingimport Foundation// A custom class called Person with two properties (a string name and an// integer age), that is a subclass of NSObject and adopts NSCoding protocol.class Person: NSObject, NSCoding { var name: String! var age: Int! // The convenience initializer for class Person // Reference // https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html#//apple_ref/doc/uid/TP40014097-CH18-ID217 convenience init(name: String, age: Int) { // self.init() is the designated initializer for class Person. // Reference // https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html#//apple_ref/doc/uid/TP40014097-CH18-ID219 self.init() self.name = name self.age = age } // The initializer init(coder:) is required by NSCoding protocol // Reference // https://developer.apple.com/documentation/foundation/nscoding // https://developer.apple.com/documentation/foundation/nscoding/1416145-init required convenience init(coder aDecoder: NSCoder) { self.init() // as! is a type casting operator // Reference // https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/doc/uid/TP40014097-CH32-ID388 self.name = aDecoder.decodeObject(forKey: "name") as! String self.age = aDecoder.decodeInteger(forKey: "age") } // The instance method encode(with:) is required by NSCoding protocol // Reference // https://developer.apple.com/documentation/foundation/nscoding // https://developer.apple.com/documentation/foundation/nscoding/1413933-encode func encode(with anEncoder: NSCoder) { if let name = name { anEncoder.encode(name, forKey: "name") } if let age = age { anEncoder.encode(age, forKey: "age") } }}// Create an array (or, generally speaking, a collection) as a container to// hold instances of our custom class type Person.// Reference// https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/CollectionTypes.htmlvar anArrayOfPersons = [Person]()print(anArrayOfPersons.count) // 0// Add two instances into anArrayOfPersons.// Reference// https://developer.apple.com/documentation/swift/array// https://developer.apple.com/documentation/swift/array/1538872-appendanArrayOfPersons.append(Person(name: "Cong", age: 33))anArrayOfPersons.append(Person(name: "Sunny", age: 2))// Archive anArrayOfPersons into NSData using NSKeyedArchiver.// Reference// https://developer.apple.com/documentation/foundation/nskeyedarchiver// https://developer.apple.com/documentation/foundation/nskeyedarchiver/1413189-archiveddatalet dataToSave = NSKeyedArchiver.archivedData(withRootObject: anArrayOfPersons)// Persist data. Storing anArrayOfPersons into UserDefaults as data.// Reference// https://developer.apple.com/documentation/foundation/userdefaults// https://developer.apple.com/documentation/foundation/userdefaults/1414067-setUserDefaults().set(dataToSave, forKey: "tagOfData")// Take our stored data (in previous step) from UserDefaults using the key// "personData". Optional binding is used to make sure the retrieved data is// not nil.// Reference// https://developer.apple.com/documentation/foundation/userdefaults// https://developer.apple.com/documentation/foundation/userdefaults/1409590-data// https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-ID333if let dataRetrieved = UserDefaults().data(forKey: "tagOfData"), // Decode our instance objects from the retrieved data // Reference // https://developer.apple.com/documentation/foundation/nskeyedunarchiver // https://developer.apple.com/documentation/foundation/nskeyedunarchiver/1413894-unarchiveobject let anArrayOfPersonsRetrieved = NSKeyedUnarchiver.unarchiveObject(with: dataRetrieved) as? [Person] { // See how many bytes the data we retrieved has. print(dataRetrieved) // 393 bytes // See if the name and age properties are the same as what we stored. print(anArrayOfPersonsRetrieved[0].name) // "Cong" print(anArrayOfPersonsRetrieved[0].age) // 45 print(anArrayOfPersonsRetrieved[1].name) // "Sunny" print(anArrayOfPersonsRetrieved[1].age) // 2 }
This link can help you
It is important your class extend NSObject
and NSCoding
, because the convert need be its class, NSCoding
is an interface to serialize and deserialize your class