Implementing NSCoding Protocol
NSCoding is simple protocol with two methods. If we want to save our custom class with all its fields we need to implement this protocol. Class that conform to
NSCoding protocol can be
serialized and deserialized into data.
public func encode(with aCoder: NSCoder)
public init?(coder aDecoder: NSCoder)
Implementation of our custom class that confirm NSCoding protocol
import Foundation
import UIKit
class AppSettings: NSObject, NSCoding {
var themeColor: UIColor
var userName: String
var isActivated: Bool
var lastActivityDate: Date
var count: Int
func encode(with aCoder: NSCoder) {
aCoder.encode(self.themeColor, forKey: "themeColor")
aCoder.encode(self.userName, forKey: "userName")
aCoder.encode(self.isActivated, forKey: "isActivated")
aCoder.encode(self.lastActivityDate, forKey: "lastActivityDate")
aCoder.encode(self.count, forKey: "count")
}
required convenience init?(coder aDecoder: NSCoder) {
guard let themeColor = aDecoder.decodeObject(forKey: "themeColor") as? UIColor,
let userName = aDecoder.decodeObject(forKey: "userName") as? String,
let lastActivityDate = aDecoder.decodeObject(forKey: "lastActivityDate") as? Date else {
return nil
}
self.init(themeColor: themeColor,
userName: userName,
isActivated: aDecoder.decodeBool(forKey: "isActivated"),
lastActivityDate: lastActivityDate,
count: aDecoder.decodeInteger(forKey: "count"))
}
init(themeColor: UIColor, userName: String, isActivated: Bool, lastActivityDate: Date, count: Int) {
self.themeColor = themeColor
self.userName = userName
self.lastActivityDate = lastActivityDate
self.isActivated = isActivated
self.count = count
}
}
Using
NSKeyedArchiver and
NSKeyedUnrachiver we can implement saving and loading of data that we get from
serizlization/deserizlization of our object (that is instance of custom class that confirm
NSCoding protocol)
Save object with NSKeyedArchiver
let data = NSKeyedArchiver.archivedData(withRootObject: self.appSettings)
let userDefaults = UserDefaults.standard
userDefaults.set(data, forKey: "appSettings")
Load object with NSKeyedUnrachiver
let userDafaults = UserDefaults.standard
if let data = userDafaults.object(forKey: "appSettings") as? Data {
self.appSettings = NSKeyedUnarchiver.unarchiveObject(with: data) as! AppSettings
} else {
self.appSettings = AppSettings(themeColor: UIColor.red,
userName: "John",
isActivated: true,
lastActivityDate: Date(),
count: 22)
}
Sources
http://nshipster.com/nscoding/
https://habrahabr.ru/company/inetra/blog/185918/
https://itvdn.com/ru/blog/article/it-intriduction-ios-dev-part7
Problems and errors
In order to make NSCoding work you need to declare the super class NSObject.
class AppSettings: NSObject, NSCoding {
...
}
Crash when implementing NSCoding in Swift
GitHub
Source code on github