Converting custom class object into NSData

后端 未结 3 864
清歌不尽
清歌不尽 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:05

    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.

    0 讨论(0)
  • 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
      }
    
    0 讨论(0)
  • 2021-02-01 04:07

    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

    Saving custom SWIFT class with NSCoding to UserDefaults

    0 讨论(0)
提交回复
热议问题