DEV Community

DanielJang
DanielJang

Posted on

How can use UserDefaults to store custom class ?

Last time, we reviewed how could use UserDefault to save user's data with common data types into local device.
Please refer to Local Data Persistence - UserDefaults (Basic)

Typically UserDefault class doesn't support saving user's data with custom class!

But if we convert user's custom class to NSData then UserDefaults class can store the converted user's custom class by NSData to local device.

Lets' coding and test...

1) Declare custom class with "Codable" protocol

  • We will convert the custom class by using JSONEncoder() and JSONEncoder will return "Data" type which can be stored through UserDefaults. At this time we should declare custom class with "Codable" keyword. "Codable" means that the custom class will be converted by JSONEncoder() for data saving and JSONDecoder() for data loading.
class Product: Codable {
    let name: String
    let modelNum: String

    init(name: String, modelNum: String){
        self.name = name
        self.modelNum = modelNum
    }
}
Enter fullscreen mode Exit fullscreen mode

2) [Save data to local device] Encoding custom class by JSONEncoder() to convert custom class as "Data" type and the converted "Data" type will be stored into local device through UserDefaults.set(Any?, forKey:) method.

let encoder = JSONEncoder()
let appleWatch = Product(name: "Apple Watch 7", modelNum: "W20215313")
do {
    let encodedData = try encoder.encode(appleWatch)
    defaults.set(encodedData, forKey: "AppleWatch")
}catch{
    print("Error encoding process\(error)")
}
Enter fullscreen mode Exit fullscreen mode

As we could study last article, you could find ".plist" file from your device to see stored data as below image.
Please refer to this link Local Data Persistence - UserDefaults (Basic)
Alt Text

3) [Load data from local device] We load converted custom class as "Data" type what we saved at 2) from local device.

  • defaults.object(forKey: ) method will grab(return) stored data from local device
  • The stored(returned) data should be "Data" type because we converted custom class to "Data" type and we stored the "Data" into local device at 2)
  • Then we should decode returned data from "Data" type to custom class again by using JSONDecoder() to use it in our code as below code.
if let data = defaults.object(forKey: "AppleWatch")as? Data {
    let decoder = JSONDecoder()
    do {
        let decodedData = try decoder.decode(Product.self, from: data)
        print(decodedData.name)
        print(decodedData.modelNum)
    }catch{
        print("Error decoding\(error)")
    }
}
Enter fullscreen mode Exit fullscreen mode

Result:
Apple Watch 7
W20215313

Finally we could see how we store common data type as integer, string, float, array, dictionary and even custom class.

Warning! UserDefaults class is not good solution to save secure data as password or banking account but UserDefault is perfect solution to save small data without secure information as user's setting. 🤗

Thank you for your reading.
Daniel JANG

Discussion (0)