如何在新版本上转换 NSKeyedArchiver 对象
How to convert NSKeyedArchiver objects over new versions
我刚刚在应用程序商店发布了一个应用程序,我的一位顾客告诉我,我应该将之前使用 NSKeyedArchiver 存储为整数的数据类型更改为双精度。
很容易更改应用程序的数据模型,但是当我在我的测试设备上重新加载应用程序时,NSKeyedUnarchiver 显然不想将 Integer 解码为 Double 并抛出 NSInvalidUnarchiveOperation 异常。
我想知道其他 iOS 开发人员会如何处理这种情况。我不想删除所有用户以前保存的数据,但这是我看到的唯一解决方案。
我的代码贴在下面。我已经评论了一些我尝试无济于事的解决方案
required convenience init?(coder aDecoder: NSCoder){
func decodeDoubles(coder aDecoder: NSCoder) throws-> (Double, Double){
print("Getting in here")
/* These are stored as Integers in previous version */
let myEarned = aDecoder.decodeDoubleForKey(PropertyKey.earnedKey)
let myTotal = aDecoder.decodeDoubleForKey(PropertyKey.totalKey)
/* App Crashes here - exception not caught */
print("After decode attempt")
return (myEarned, myTotal)
}
let myID = aDecoder.decodeIntegerForKey(PropertyKey.idKey)
let myName = aDecoder.decodeObjectForKey(PropertyKey.nameKey) as! String
let myWeight = aDecoder.decodeIntegerForKey(PropertyKey.weightKey)
/* Throws exception */
//let myEarned = aDecoder.decodeDoubleForKey(PropertyKey.earnedKey)
//let myTotal = try! aDecoder.decodeDoubleForKey(PropertyKey.totalKey)
var myEarned: Double = 0
var myTotal: Double = 0
do {
(myEarned, myTotal) = try decodeDoubles(coder: aDecoder)
} catch {
print("Exception caught - \(error)")
myEarned = Double(aDecoder.decodeIntegerForKey(PropertyKey.earnedKey))
myTotal = Double(aDecoder.decodeIntegerForKey(PropertyKey.totalKey))
}
self.init(id: myID, name: myName, weight: myWeight, earned: myEarned, total: myTotal)
}
您可能需要创建一个函数来升级存档,在应用加载时,将密钥作为整数读入,然后将其作为双精度写回,然后您的应用的其余部分可以读写它通常是双倍的。您将需要一个新密钥来标记您已完成升级,这样您就不会再这样做,也不会为新用户这样做。
我刚刚在应用程序商店发布了一个应用程序,我的一位顾客告诉我,我应该将之前使用 NSKeyedArchiver 存储为整数的数据类型更改为双精度。
很容易更改应用程序的数据模型,但是当我在我的测试设备上重新加载应用程序时,NSKeyedUnarchiver 显然不想将 Integer 解码为 Double 并抛出 NSInvalidUnarchiveOperation 异常。
我想知道其他 iOS 开发人员会如何处理这种情况。我不想删除所有用户以前保存的数据,但这是我看到的唯一解决方案。
我的代码贴在下面。我已经评论了一些我尝试无济于事的解决方案
required convenience init?(coder aDecoder: NSCoder){
func decodeDoubles(coder aDecoder: NSCoder) throws-> (Double, Double){
print("Getting in here")
/* These are stored as Integers in previous version */
let myEarned = aDecoder.decodeDoubleForKey(PropertyKey.earnedKey)
let myTotal = aDecoder.decodeDoubleForKey(PropertyKey.totalKey)
/* App Crashes here - exception not caught */
print("After decode attempt")
return (myEarned, myTotal)
}
let myID = aDecoder.decodeIntegerForKey(PropertyKey.idKey)
let myName = aDecoder.decodeObjectForKey(PropertyKey.nameKey) as! String
let myWeight = aDecoder.decodeIntegerForKey(PropertyKey.weightKey)
/* Throws exception */
//let myEarned = aDecoder.decodeDoubleForKey(PropertyKey.earnedKey)
//let myTotal = try! aDecoder.decodeDoubleForKey(PropertyKey.totalKey)
var myEarned: Double = 0
var myTotal: Double = 0
do {
(myEarned, myTotal) = try decodeDoubles(coder: aDecoder)
} catch {
print("Exception caught - \(error)")
myEarned = Double(aDecoder.decodeIntegerForKey(PropertyKey.earnedKey))
myTotal = Double(aDecoder.decodeIntegerForKey(PropertyKey.totalKey))
}
self.init(id: myID, name: myName, weight: myWeight, earned: myEarned, total: myTotal)
}
您可能需要创建一个函数来升级存档,在应用加载时,将密钥作为整数读入,然后将其作为双精度写回,然后您的应用的其余部分可以读写它通常是双倍的。您将需要一个新密钥来标记您已完成升级,这样您就不会再这样做,也不会为新用户这样做。