title: Properties reset when using NSKeyedArchiver on UserDefaults
body: <p>I have an array of <code>SKSpriteNode</code> objects that I want to persist to <code>UserDefaults</code>. In the code below (<a href="https://github.com/prinomen/userDefaultsDemo" rel="nofollow noreferrer">or see demo project on GitHub</a>), I use <code>NSKeyedUnarchiver</code> to encode the array as data before setting it to defaults. But when I unarchive the data, the <code>engineSize</code> property of the objects is reset to the default value of 0.</p>
  
  <p><strong>Car.swift</strong></p>
  
  <pre><code>import SpriteKit
  
  class Car: SKSpriteNode {
      var engineSize: Int = 0
  
      init() {
          super.init(texture: nil, color: .blue, size: CGSize(width: 100, height: 100))
      }
  
      required init?(coder aDecoder: NSCoder) {
          super.init(coder: aDecoder)
      }
  }
  </code></pre>
  
  <p><strong>GameScene.swift</strong></p>
  
  <pre><code>import SpriteKit
  
  class GameScene: SKScene {
      let defaults = UserDefaults.standard
      var carArray = [Car]()
  
      override func didMove(to view: SKView) {
          for _ in 1...3 {
              let car = Car()
              car.engineSize = 2000
              carArray.append(car)
          }
  
          // Save to defaults
          defaults.set(NSKeyedArchiver.archivedData(withRootObject: carArray), forKey: "carArrayKey")
  
          // Restore from defaults
          let arrayData = defaults.data(forKey: "carArrayKey")
          carArray = NSKeyedUnarchiver.unarchiveObject(with: arrayData!) as! [Car]
      }
  
      override func touchesBegan(_ touches: Set&lt;UITouch&gt;, with event: UIEvent?) {
          for c in carArray {
              print("Car's engine size is \(c.engineSize)")
          }
      }
  }
  </code></pre>
  
  <p><a href="https://stackoverflow.com/a/41845020/4376309">This answer</a> led me to try implementing encoder/decoder methods on the <code>Car</code> class:</p>
  
  <p><strong>Car.swift (updated)</strong></p>
  
  <pre><code>import SpriteKit
  
  class Car: SKSpriteNode {
      var engineSize: Int = 0
  
      init() {
          super.init(texture: nil, color: .blue, size: CGSize(width: 100, height: 100))
      }
  
      required convenience public init(coder decoder: NSCoder) {
          self.init()
  
          if let engineSize = decoder.decodeObject(forKey: "engineSize") as? Int {
              self.engineSize = engineSize
          }
      }
  
      func encodeWithCoder(coder : NSCoder) {
          coder.encode(self.engineSize, forKey: "engineSize")
      }
  }
  </code></pre>
  
  <p>However, this doesn't seem to be working. <code>GameScene</code> is still printing the <code>engineSize</code> as 0. Am I implementing the coder/decoder wrong? What can I do to prevent the <code>engineSize</code> properties from resetting to 0 when they are restored from defaults?</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>Here is my updated <code>Car</code> class as I'm trying to get it to work with rmaddy's suggestions:</p>
  
  <pre><code>import SpriteKit
  
  class Car: SKSpriteNode {
      var engineSize: Int = 0
  
      init() {
          super.init(texture: nil, color: .blue, size: CGSize(width: 100, height: 100))
      }
  
      required init?(coder decoder: NSCoder) {
          super.init(coder: decoder)
          if let engineSize = decoder.decodeObject(forKey: "engineSize") as? Int {
              self.engineSize = engineSize
          }
      }
  
      func encodeWithCoder(coder : NSCoder) {
          super.encode(with: coder)
          coder.encode(self.engineSize, forKey: "engineSize")
      }
  }
  </code></pre>
  
  <p>The code compiles and runs but the <code>engineSize</code> property is still being reset to 0 when saving to defaults.</p>