How to store custom objects in NSUserDefaults?


In this article we’ll learn how to store custom objects in our application, but before you learn how to store custom object let’s see what are custom object?

A custom object is any class or structure or any other data that is not a native data type like Int, Double, String etc. Storing data in NSUserDefaults is a three step process.

Creating the custom Object

We’ll create a custom class Person that will have an age variable, and name variable.

class Person: NSObject, NSCoding {
   var name: String
   var age: Int
   init(name: String, age: Int) {
      self.name = name
      self.age = age
   }
   required convenience init(coder aCoder: NSCoder) {
      let name = aCoder.decodeObject(forKey: "name") as! String
      let age = aCoder.decodeInteger(forKey: "age")
      self.init(name: name, age: age)
   }
   func encode(with acoder: NSCoder) {
      acoder.encode(age,forKey: "age")
      acoder.encode(name,forKey: "name")
   }
}

Encoding the custom object

In this step we’ll create an array of person object, call it people and initialize it with random data. Once we create that object we’ll use NSKeyedArchiver to archive this object and later store in userDefaults.

let people = [
   Person.init(name: "P1", age: 1),
   Person.init(name: "P2", age: 2),
   Person.init(name: "P3", age: 3),
]
let encoded = NSKeyedArchiver.archivedData(withRootObject: people)
UserDefaults.standard.set(encoded, forKey: "encodedData")

Now we have successfully saved the archived object in core data, it’s time we unarchive and print that object.

Decoding the custom object

Similar to NSKeyedArchiver we have NSKeyedUnarchiver which we’ll use to unarchive this object.

let decoded = UserDefaults.standard.object(forKey: "encodedData") as! Data
let decodedPeople = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! [Person]

Now this “decodedPeople” object contains the object we created in the second step.

We can perform the desired operation with at object. Now let’s see how the ViewController file looks like;

import UIKit
class ViewController: UIViewController {
   override func viewDidLoad() {
      super.viewDidLoad()
      // Do any additional setup after loading the view, typically from a nib.
      let people = [
         Person.init(name: "P1", age: 1),
         Person.init(name: "P2", age: 2),
         Person.init(name: "P3", age: 3),
      ]
      let encoded = NSKeyedArchiver.archivedData(withRootObject: people)
      UserDefaults.standard.set(encoded, forKey: "encodedData")
      print("data decoded, encoding now")
      let decoded = UserDefaults.standard.object(forKey: "encodedData") as! Data
      let decodedPeople = NSKeyedUnarchiver.unarchiveObject(with: decoded) as! [Person]
      print(decodedPeople)
   }
}

Now put a break point on last print statement and run this code, when executed run this command

po decodedPeople.first?.name

which will result into

Optional<String>
- some : "P1"

This is how it looks in the end.

Updated on: 27-Jun-2020

453 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements