It's now easier with Swift 4 to encode / decode to and from JSON or Properties list.
But I can't find how to encode to Data using Codable, without using Objective-C methods initWithCoder
and encodeWithCoder
.
Considering this simple class:
struct Question: Codable {
var title: String
var answer: Int
var question: Int
}
How can I encode it to Data using CodingKeys
and not initWithCoder
and encodeWithCoder
?
EDIT: I also need to be able to deserialize objects previously saved in userdefaults using NSKeyedArchiver.
Well, you no longer need NSKeyedArchiver
.
Try this:
let questionObj = Question(title: "WWDC, 2017", answer: 1,question:1)
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(questionObj) {
UserDefaults.standard.set(encoded, forKey: "K_Question")
}
let decoder = JSONDecoder()
if let questionData = UserDefaults.standard.data(forKey: "K_Question"),
let question = try? decoder.decode(Question.self, from: questionData) {
print(question.title)
print(question.answer)
print(question.question)
}
Swift 5: a great simple extension for UserDefaults:
extension UserDefaults {
func save<T: Codable>(_ object: T, forKey key: String) {
let encoder = JSONEncoder()
if let encodedObject = try? encoder.encode(object) {
UserDefaults.standard.set(encodedObject, forKey: key)
UserDefaults.standard.synchronize()
}
}
func getObject<T: Codable>(forKey key: String) -> T? {
if let object = UserDefaults.standard.object(forKey: key) as? Data {
let decoder = JSONDecoder()
if let decodedObject = try? decoder.decode(T.self, from: object) {
return decodedObject
}
}
return nil
}
}
Usage
save
UserDefaults.standard.save(currentUser, forKey: "currentUser")
get
let user: User? = UserDefaults.standard.getObject(forKey: "currentUser")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With