Converting custom class object into NSData

后端 未结 3 866
清歌不尽
清歌不尽 2021-02-01 03:20

I have a custom class that I want to save into NSUserDefaults. I am told that I need to convert the class object into data in order to save it to NSUserDefaul

3条回答
  •  清歌不尽
    2021-02-01 04:06

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

提交回复
热议问题