【问题标题】:NSKeyedArchiver: casting Data returning nil - SwiftNSKeyedArchiver:转换数据返回 nil - Swift
【发布时间】:2019-02-12 18:14:47
【问题描述】:

好吧,在这里调查了几个类似的主题,按照建议完成了所有工作,但是当我尝试将解码的对象转换为我的类型时,我的计算属性“previousUserData”返回 nil。怎么了?

@objc class PreviousUserData: NSObject, NSCoding {

var name: String
var phone: String
var email: String

func encode(with aCoder: NSCoder) {
    aCoder.encode(name, forKey: "name")
    aCoder.encode(phone, forKey: "phone")
    aCoder.encode(email, forKey: "email")
}

required convenience init?(coder aDecoder: NSCoder) {
    guard
        let name = aDecoder.decodeObject(forKey: "name") as? String,
        let phone = aDecoder.decodeObject(forKey: "phone") as? String,
        let email = aDecoder.decodeObject(forKey: "email") as? String
        else {
            return nil
    }
    self.init(name: name, phone: phone, email: email)
}

init(name: String, phone: String, email: String) {
    self.name = name
    self.phone = phone
    self.email = email
}
}

unarchived 返回 nil,但键“userdata”的数据存在

    var previousUserData: PreviousUserData? {
    get {
        if let object = UserDefaults.standard.object(forKey: "userdata") as? Data {
            let unarchived = NSKeyedUnarchiver.unarchiveObject(with: object) as? PreviousUserData
            return unarchived
        }
        return nil
    }
    set {
        let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: previousUserData as Any)
        UserDefaults.standard.setValue(encodedData, forKey: "userdata")
    }
    }

【问题讨论】:

    标签: swift nscoding nskeyedarchiver


    【解决方案1】:

    实际上你不能得到有效的数据,因为setter是错误的。您必须保存newValue 而不是previousUserData

    这是一个略微优化的版本

    var previousUserData: PreviousUserData? {
        get {
            guard let data = UserDefaults.standard.data(forKey: "userdata") else { return nil }
            return NSKeyedUnarchiver.unarchiveObject(with: data) as? PreviousUserData
        }
        set {
            guard let newValue = newValue else { return }
            let encodedData = NSKeyedArchiver.archivedData(withRootObject: newValue)
            UserDefaults.standard.set(encodedData, forKey: "userdata")
        }
    }
    

    NSCoding 很重。在这种情况下,我建议使用Codable 将数据序列化为 JSON 或属性列表。它摆脱了@objcclassNSObject,并将整个代码简化为

    struct PreviousUserData : Codable {
        var name: String
        var phone: String
        var email: String
    }
    
    var previousUserData: PreviousUserData? {
        get {
            guard let data = UserDefaults.standard.data(forKey: "userdata") else { return nil }
            return try? JSONDecoder().decode(PreviousUserData.self, from: data)
        }
        set {
            guard let newValue = newValue, let encodedData = try? JSONEncoder().encode(newValue) else { return }
            UserDefaults.standard.set(encodedData, forKey: "userdata")
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-25
      • 2018-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多