如果自定義類(lèi)型需要存放到UserDefaults
中需要自定義類(lèi)型繼承NSObject
以及NSCoding
、NSSecureCoding
NSSecureCoding
繼承自NSCoding
呈昔,只用實(shí)現(xiàn)其中一個(gè)
public protocol NSCoding {
public func encode(with aCoder: NSCoder)
public init?(coder aDecoder: NSCoder) // NS_DESIGNATED_INITIALIZER
}
public protocol NSSecureCoding : NSCoding {
// This property must return YES on all classes that allow secure coding. Subclasses of classes that adopt NSSecureCoding and override initWithCoder: must also override this method and return YES.
// The Secure Coding Guide should be consulted when writing methods that decode data.
public static var supportsSecureCoding: Bool { get }
}
以下是我自定義的class
class People: NSObject, NSSecureCoding {
static var supportsSecureCoding: Bool = true
enum CodeKey: String {
case nameKey = "name"
case ageKey = "age"
case dogKey = "dog"
}
var name: String = ""
var age: Int = 0
var dog: Dog
override init() {
name = "123"
age = 1
dog = Dog(name: "lanbo", age: 2)
}
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: CodeKey.nameKey.rawValue)
aCoder.encode(age, forKey: CodeKey.ageKey.rawValue)
aCoder.encode((try? JSONEncoder().encode(dog)) ?? Data())
}
required init?(coder aDecoder: NSCoder) {
name = aDecoder.decodeObject(forKey: CodeKey.nameKey.rawValue) as? String ?? ""
age = aDecoder.decodeInteger(forKey: CodeKey.ageKey.rawValue)
dog = try! JSONDecoder().decode(Dog.self, from: aDecoder.decodeData() ?? Data())
}
}
struct Dog: Codable {
var name: String
var age: Int
}
使用UserDefaults
進(jìn)行存取
let albert = People()
let obj = try? NSKeyedArchiver.archivedData(withRootObject: albert, requiringSecureCoding: false)
UserDefaults.standard.set(obj, forKey: "albert")
UserDefaults.standard.synchronize()
if let per = UserDefaults.standard.object(forKey: "albert") as? Data {
let p = try! NSKeyedUnarchiver.unarchivedObject(ofClass: People.self, from: per)
print(p?.dog) //Optional(CacheDemo.Dog(name: "lanbo", age: 2))
}
單獨(dú)存取struct
時(shí)也可以直接用Codable
協(xié)議把結(jié)構(gòu)體轉(zhuǎn)化成Data
后存儲(chǔ)
let dog = Dog(name: "333", age: 3)
let pp = try? JSONEncoder().encode(dog)
UserDefaults.standard.set(pp, forKey: "dog")
UserDefaults.standard.synchronize()
if let d = UserDefaults.standard.object(forKey: "dog") as? Data {
if let dd = try? JSONDecoder().decode(Dog.self, from: d) {
print(dd.name) // 333
}
}
其中NSKeyedUnarchiver.unarchivedObject
這個(gè)方法需要實(shí)現(xiàn)NSSecureCoding
才能夠使用衩婚,NSCoding
應(yīng)該使用NSKeyedUnarchiver.unarchiveObject(with: Data)
但是這個(gè)方法在iOS12廢棄了贺拣,應(yīng)該是蘋(píng)果推薦使用NSSecureCoding
.
@available(iOS, introduced: 2.0, deprecated: 12.0, message: "Use +unarchivedObjectOfClass:fromData:error: instead")
open class func unarchiveObject(with data: Data) -> Any?