NSKeyedUnarchiver,如何安全地解码 Any 类型
NSKeyedUnarchiver, how to decode securely the Any type
我有一组安全编码到 10.13 之前的数据文件中的字典。希望它们可以在 10.13 中通过 API 更改为 NSKeyedArchiver/NSKeyedUnarchiver 来解码。现在我无法在较新的 API 中安全地解码类型化数组 [[String: Any]]。有什么办法吗?
// the older coding method, pre 10.14 . This works on 10.14.6
let arr: [[String: Any]] = [["one": "data"],["two": Double(2.0)]]
//let arr: [[String: String]] = [["one": "data"],["two": "data2"]]
let mutableData = NSMutableData()
let archiver: NSKeyedArchiver = NSKeyedArchiver(forWritingWith: mutableData)
archiver.requiresSecureCoding = true
archiver.encode(arr, forKey: "mydata")
archiver.finishEncoding()
let unarchiver = try NSKeyedUnarchiver(forReadingWith: mutableData as Data)
let obj5 = unarchiver.decodeObject(forKey: "mydata")
unarchiver.finishDecoding()
if (obj5 != nil) {
let dataobj = obj5 as! [[String: Any]]
print(dataobj)
}
// the newer coding method, 10.13+ . This gives obj6 as nil on 10.14.6
let archiver2 = NSKeyedArchiver(requiringSecureCoding: true)
archiver2.encode(arr, forKey: "mydata")
let data = archiver2.encodedData
let unarchiver2 = try NSKeyedUnarchiver(forReadingFrom: data)
unarchiver2.requiresSecureCoding = true
if unarchiver2.containsValue(forKey: "mydata") {
let obj6 = unarchiver2.decodeObject(forKey: "mydata")
//let obj6 = unarchiver2.decodeDecodable([[String: String]].self, forKey: "mydata")
unarchiver2.finishDecoding()
if (obj6 != nil) {
let dataobj = obj6 as! [[String: Any]]
print(dataobj)
}
else {
print("nogood")
}
}
else {
print("phoey")
}
在 10.14.6 的操场上执行时 returns:
[["one": data], ["two": 2]]
nogood
你的第二个例子的问题是你没有使用安全解码。
您实际上不需要此示例的密钥,所以让我们简化并演示如何使用根对象执行此操作:
do {
let arr: [[String: Any]] = [["one": "data"],["two": Double(2.0)]]
let data = try NSKeyedArchiver.archivedData(
withRootObject: arr, requiringSecureCoding: true)
if let output = try NSKeyedUnarchiver.unarchivedObject(
ofClasses: [NSArray.self, NSDictionary.self], from: data)
as? [[String:Any]] {
print(output)
} else {
print("oops")
}
} catch {
print(error)
}
这个 是 安全解码,正如 unarchivedObject(ofClasses:from:)
上的文档所表明的那样。
为了完整起见,我将使用一个键来演示同样的事情,更多的是按照您的代码行:
do {
let arr: [[String: Any]] = [["one": "data"],["two": Double(2.0)]]
let arch = NSKeyedArchiver(requiringSecureCoding: true)
arch.requiresSecureCoding = true
arch.encode(arr, forKey: "mydata")
let data = arch.encodedData
let unarch = try NSKeyedUnarchiver(forReadingFrom:data)
if let output = try unarch.decodeTopLevelObject(
of: [NSArray.self, NSDictionary.self], forKey: "mydata")
as? [[String:Any]] {
print(output)
} else {
print("oops")
}
} catch {
print(error)
}
我有一组安全编码到 10.13 之前的数据文件中的字典。希望它们可以在 10.13 中通过 API 更改为 NSKeyedArchiver/NSKeyedUnarchiver 来解码。现在我无法在较新的 API 中安全地解码类型化数组 [[String: Any]]。有什么办法吗?
// the older coding method, pre 10.14 . This works on 10.14.6
let arr: [[String: Any]] = [["one": "data"],["two": Double(2.0)]]
//let arr: [[String: String]] = [["one": "data"],["two": "data2"]]
let mutableData = NSMutableData()
let archiver: NSKeyedArchiver = NSKeyedArchiver(forWritingWith: mutableData)
archiver.requiresSecureCoding = true
archiver.encode(arr, forKey: "mydata")
archiver.finishEncoding()
let unarchiver = try NSKeyedUnarchiver(forReadingWith: mutableData as Data)
let obj5 = unarchiver.decodeObject(forKey: "mydata")
unarchiver.finishDecoding()
if (obj5 != nil) {
let dataobj = obj5 as! [[String: Any]]
print(dataobj)
}
// the newer coding method, 10.13+ . This gives obj6 as nil on 10.14.6
let archiver2 = NSKeyedArchiver(requiringSecureCoding: true)
archiver2.encode(arr, forKey: "mydata")
let data = archiver2.encodedData
let unarchiver2 = try NSKeyedUnarchiver(forReadingFrom: data)
unarchiver2.requiresSecureCoding = true
if unarchiver2.containsValue(forKey: "mydata") {
let obj6 = unarchiver2.decodeObject(forKey: "mydata")
//let obj6 = unarchiver2.decodeDecodable([[String: String]].self, forKey: "mydata")
unarchiver2.finishDecoding()
if (obj6 != nil) {
let dataobj = obj6 as! [[String: Any]]
print(dataobj)
}
else {
print("nogood")
}
}
else {
print("phoey")
}
在 10.14.6 的操场上执行时 returns:
[["one": data], ["two": 2]]
nogood
你的第二个例子的问题是你没有使用安全解码。
您实际上不需要此示例的密钥,所以让我们简化并演示如何使用根对象执行此操作:
do {
let arr: [[String: Any]] = [["one": "data"],["two": Double(2.0)]]
let data = try NSKeyedArchiver.archivedData(
withRootObject: arr, requiringSecureCoding: true)
if let output = try NSKeyedUnarchiver.unarchivedObject(
ofClasses: [NSArray.self, NSDictionary.self], from: data)
as? [[String:Any]] {
print(output)
} else {
print("oops")
}
} catch {
print(error)
}
这个 是 安全解码,正如 unarchivedObject(ofClasses:from:)
上的文档所表明的那样。
为了完整起见,我将使用一个键来演示同样的事情,更多的是按照您的代码行:
do {
let arr: [[String: Any]] = [["one": "data"],["two": Double(2.0)]]
let arch = NSKeyedArchiver(requiringSecureCoding: true)
arch.requiresSecureCoding = true
arch.encode(arr, forKey: "mydata")
let data = arch.encodedData
let unarch = try NSKeyedUnarchiver(forReadingFrom:data)
if let output = try unarch.decodeTopLevelObject(
of: [NSArray.self, NSDictionary.self], forKey: "mydata")
as? [[String:Any]] {
print(output)
} else {
print("oops")
}
} catch {
print(error)
}