[最近,我正在使用NSKeyedArchiver
和NSKeyedUnarchiver
处理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
,但不适用于Date
。 print
输出:
Optional("String") nil
我不知道为什么会这样。
[您需要指定要解码的对象类型,并且由于要解码Date
对象,因此需要了解NSKeyedArchiver
和NSKeyedUnarchiver
会将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
协议与JSONEncoder
和JSONDecoder
结合使用,它们具有非常好的dateDecodingStrategy
,可以在编码和解码时指定自定义日期格式,并且还支持解码[C0 ]直接创建对象而不桥接到obj-c Date
,当您尝试将对象作为json有效负载发送或通过网络调用对其进行解码时,这是很好的选择
这里是一个例子
NSDate