为什么NSKeyedUnarchiver`无法为Date解码

问题描述 投票:0回答:1

[最近,我正在使用NSKeyedArchiverNSKeyedUnarchiver处理iOS上的持久性。但是我遇到了一些问题。

这里是代码:

import Foundation

class Model {
    static let instance = Model()
    static let DocumentsDirectory = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
    static let TestArchiveURL = DocumentsDirectory.appendingPathComponent("t")

    static func getInstance() -> Model {
        return instance
    }
    var str = "String"
    var date = Date()

    func save() {
        let coder = NSKeyedArchiver(requiringSecureCoding: false)
        coder.encode(str, forKey: ModelPropertyKey.str)
        coder.encode(date, forKey: ModelPropertyKey.date)
        do {
            try coder.encodedData.write(to: Model.TestArchiveURL)
        } catch {
            print("error write to file: " + error.localizedDescription)
        }

        do {
            let data = try Data(contentsOf: Model.TestArchiveURL)
            let decoder = try NSKeyedUnarchiver(forReadingFrom: data)
            let strGot = decoder.decodeObject(forKey: ModelPropertyKey.str) as? String
            let dateGot = decoder.decodeObject(forKey: ModelPropertyKey.date) as? Date
            print("\(String(describing: strGot)) \(String(describing: dateGot))")
        } catch {
            print("Error read from file")
        }

    }
}

我用encode(:forKey:)编码数据,并用encodedData.write(to:)获得持久性。然后,我尝试使用NSKeyedUnarchiver(forReadingFrom:)decodeObject(forKey:)从磁盘读取数据。但是此策略适用于String,但不适用于Dateprint输出:

Optional("String") nil

我不知道为什么会这样。

ios swift persistence
1个回答
0
投票

[您需要指定要解码的对象类型,并且由于要解码Date对象,因此需要了解NSKeyedArchiverNSKeyedUnarchiver会将Date Swift对象桥接到NSDate Objective-C swift和obj-c兼容的对象,因为NSKeyedArchiver使用NSCoding,并且Date不符合NSCoding

为此,将您的解码更改为这样

let dateGot = decoder.decodeObject(of: NSDate.self, forKey: ModelPropertyKey.date)! as Date

但是我建议您将快速的Codable协议与JSONEncoderJSONDecoder结合使用,它们具有非常好的dateDecodingStrategy,可以在编码和解码时指定自定义日期格式,并且还支持解码[C0 ]直接创建对象而不桥接到obj-c Date,当您尝试将对象作为json有效负载发送或通过网络调用对其进行解码时,这是很好的选择

这里是一个例子

NSDate
© www.soinside.com 2019 - 2024. All rights reserved.