NSKeyedArchiver 不持久化数据 Swift 3
NSKeyedArchiver not persisting data Swift 3
我有一个正在生产的应用程序,我正在尝试从 Swift 2.2 转换为 Swift 3。我已经在两个 [=22= 中尝试了 Swift 3 代码] 8.1 和 XCode 8.2.
以下 Swift 2 代码完美运行:
func saveItemsToCache() {
NSKeyedArchiver.archiveRootObject(items, toFile: itemsCachePath)
}
func loadItemsFromCache() {
if let cachedItems = NSKeyedUnarchiver.unarchiveObjectWithFile(itemsCachePath) as? [TruckItem] {
items = cachedItems
}
}
var itemsCachePath: String {
let documentsURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
let fileURL = documentsURL.URLByAppendingPathComponent("Trucks.dat")
return fileURL.path!
}
但是当我使用为 Swift 3:
转换的相同代码时,数据没有被保留
func saveItemsToCache() {
print("SAVED TRUCKS:", items)
NSKeyedArchiver.archiveRootObject(items, toFile: itemsCachePath)
}
func loadItemsFromCache() {
if let cachedItems = NSKeyedUnarchiver.unarchiveObject(withFile: itemsCachePath) as? [TruckItem] {
items = cachedItems
print("LOADED TRUCKS:", items)
}
}
var itemsCachePath: String {
let documentsURL = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
let fileURL = documentsURL.appendingPathComponent("Trucks.dat")
return fileURL.path
}
示例控制台输出:
SAVED TRUCKS: [<TruckTelematics.TruckItem: 0xc852380>, <TruckTelematics.TruckItem: 0x9b23ba0>]
LOADED TRUCKS: []
我最近发现问题根本不在于 NSKeyedArchiver,而是在于我的 NSObject 子类 TruckItem
.
中的 convenience init?(coder aDecoder: NSCoder)
方法
在 Swift 2.2 中,您将像这样解码不同的对象属性:
let IMEI = aDecoder.decodeObject(forKey: CodingKeys.IMEI) as! String
let active = aDecoder.decodeObject(forKey: CodingKeys.active) as! Bool
let daysInactive = aDecoder.decodeObject(forKey: CodingKeys.daysInactive) as! Int
在 Swift 3 中,不再对所有 属性 类型使用 decodeObject()
,现在似乎有一些新函数需要注意。这是在 Swift 3 中解码的相同对象属性:
let IMEI = aDecoder.decodeObject(forKey: CodingKeys.IMEI) as! String
let active = aDecoder.decodeBool(forKey: CodingKeys.active)
let daysInactive = aDecoder.decodeInteger(forKey: CodingKeys.daysInactive)
我花了很长时间才发现这一点,希望这个答案能让其他用户免于类似的挫败感。
我有一个正在生产的应用程序,我正在尝试从 Swift 2.2 转换为 Swift 3。我已经在两个 [=22= 中尝试了 Swift 3 代码] 8.1 和 XCode 8.2.
以下 Swift 2 代码完美运行:
func saveItemsToCache() {
NSKeyedArchiver.archiveRootObject(items, toFile: itemsCachePath)
}
func loadItemsFromCache() {
if let cachedItems = NSKeyedUnarchiver.unarchiveObjectWithFile(itemsCachePath) as? [TruckItem] {
items = cachedItems
}
}
var itemsCachePath: String {
let documentsURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
let fileURL = documentsURL.URLByAppendingPathComponent("Trucks.dat")
return fileURL.path!
}
但是当我使用为 Swift 3:
转换的相同代码时,数据没有被保留func saveItemsToCache() {
print("SAVED TRUCKS:", items)
NSKeyedArchiver.archiveRootObject(items, toFile: itemsCachePath)
}
func loadItemsFromCache() {
if let cachedItems = NSKeyedUnarchiver.unarchiveObject(withFile: itemsCachePath) as? [TruckItem] {
items = cachedItems
print("LOADED TRUCKS:", items)
}
}
var itemsCachePath: String {
let documentsURL = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
let fileURL = documentsURL.appendingPathComponent("Trucks.dat")
return fileURL.path
}
示例控制台输出:
SAVED TRUCKS: [<TruckTelematics.TruckItem: 0xc852380>, <TruckTelematics.TruckItem: 0x9b23ba0>]
LOADED TRUCKS: []
我最近发现问题根本不在于 NSKeyedArchiver,而是在于我的 NSObject 子类 TruckItem
.
convenience init?(coder aDecoder: NSCoder)
方法
在 Swift 2.2 中,您将像这样解码不同的对象属性:
let IMEI = aDecoder.decodeObject(forKey: CodingKeys.IMEI) as! String
let active = aDecoder.decodeObject(forKey: CodingKeys.active) as! Bool
let daysInactive = aDecoder.decodeObject(forKey: CodingKeys.daysInactive) as! Int
在 Swift 3 中,不再对所有 属性 类型使用 decodeObject()
,现在似乎有一些新函数需要注意。这是在 Swift 3 中解码的相同对象属性:
let IMEI = aDecoder.decodeObject(forKey: CodingKeys.IMEI) as! String
let active = aDecoder.decodeBool(forKey: CodingKeys.active)
let daysInactive = aDecoder.decodeInteger(forKey: CodingKeys.daysInactive)
我花了很长时间才发现这一点,希望这个答案能让其他用户免于类似的挫败感。