美文网首页
NSCoding(NSSucureCoding)归档自定义cla

NSCoding(NSSucureCoding)归档自定义cla

作者: 林夕copy | 来源:发表于2019-09-28 13:33 被阅读0次

    如果自定义类型需要存放到UserDefaults中需要自定义类型继承NSObject以及NSCodingNSSecureCoding

    NSSecureCoding继承自NSCoding,只用实现其中一个

    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进行存取

    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))
    }
            
    

    单独存取struct时也可以直接用Codable协议把结构体转化成Data后存储

    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这个方法需要实现NSSecureCoding才能够使用,NSCoding应该使用NSKeyedUnarchiver.unarchiveObject(with: Data)但是这个方法在iOS12废弃了,应该是苹果推荐使用NSSecureCoding.

    @available(iOS, introduced: 2.0, deprecated: 12.0, message: "Use +unarchivedObjectOfClass:fromData:error: instead")
        open class func unarchiveObject(with data: Data) -> Any?
    

    相关文章

      网友评论

          本文标题:NSCoding(NSSucureCoding)归档自定义cla

          本文链接:https://www.haomeiwen.com/subject/sjzzuctx.html