将自定义类对象转换为NSData

我有一个自定义类,我想保存到NSUserDefaults。 我被告知,我需要将类对象转换为数据,以便将其保存到NSUserDefaults。 我发现很多离散的string或整数NSData的例子,但没有自定义类到NSData。 我对NSData编码的复杂性知之甚less。任何帮助都是值得赞赏的

编辑:虽然我明白这里有类似的答案,他们都没有在斯威夫特。 语言之间的翻译是可行的,但是这是非常单调的,有时非常直观。

这里有一个简单的例子:

//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 } } 

testing与操场。

希望这可以帮助。

这个链接可以帮助你

重要的是你的类扩展NSObject和NSCoding,因为转换需要它的类, NSCoding是一个接口来序列化和反序列化你的类

将具有NSCoding的自定义SWIFT类保存到UserDefaults

下面的示例代码是基于Richie Rich的答案(见上),并在此环境中通过testing:

  • 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 NSCoding import 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.html var 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-append anArrayOfPersons.append(Person(name: "Cong", age: 32)) 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-archiveddata let 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-set UserDefaults().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-ID333 if 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 }