Storing Struct in UserDefaults
There is a post by Paul Hudson where he explains how structs can be stored in UserDefaults.
He recommends converting the value to Data
type first and then store it directly in UserDefaults.
Similarly for retreving, get the Data
and decode it to get the desired type back
So to make it more convenient and Swifty, I have written the following extension
extension UserDefaults {
private static let encoder = JSONEncoder()
private static let decoder = JSONDecoder()
func encodeAndSet<T>(_ value: T, forKey defaultName: String) where T: Encodable {
if let encoded = try? Self.encoder.encode(value) {
set(encoded, forKey: defaultName)
}
}
open func decodedObject<T>(forKey defaultName: String) -> T? where T: Decodable {
guard let data = data(forKey: defaultName) else {
return nil
}
return try? Self.decoder.decode(T.self, from: data)
}
}
After adding above methods to UserDefaults one can easily store Codable types in UserDefaults with just one line of code
struct Person: Codable {
var name: String
var age: Int
}
var john = Person(name: "John", age: 41)
UserDefaults.standard.encodeAndSet(john, forKey: "user")
let getJohn: Person? = UserDefaults.standard.decodedObject(forKey: "user")
print(getJohn) // print Optional(FR.Person(name: "John", age: 41))