iOS 16.4 deprecates unarchiveTopLevelObjectWithData(_:)
and should be replaced with unarchivedObject(ofClass:from:)
.
When you archived a Swift Dictionary like [String: Any]
, how do you use the newer API to unarchive it?
NSKeyedUnarchiver.unarchivedObject(ofClass: [String: Any].self, from: data)
results in a build time error:
Static method ‘unarchivedObject(ofClass:from:)’ requires that ‘[String : Any]’ conform to ‘NSCoding’
//create the data from dictionary
let dictionary: [String: Any] = ["Text": "Hello", "Number": 1, "Array": ["Hello", "World"]]
let data = try! NSKeyedArchiver.archivedData(withRootObject: dictionary, requiringSecureCoding: true)
//and later get the dictionary from the data
let dictionary = try? NSKeyedUnarchiver.unarchivedObject(ofClass: [String: Any].self, from: data) //sorry no can do
2
Answers
Since the Swift dictionary of type
[String: Any]
doesn’t conform toNSCoding
, you need to drop back to usingNSDictionary
. Since you are also using secure coding, you also need to list all types that can be in the dictionary.You will need to use the
unarchivedObject(ofClasses:from:)
method so you can list all of the classes.You may also end up needing to add
NSString.self
andNSNumber.self
to the list of classes. Keep adding the classes that appear in the error message until it works.You can use this dummy object:
[NSObject.self]
instead of[NSDictionary.self, NSArray.self ...... ]
.With this, you cover all NS cases.
It worked for me, although purple message appears (Apple always on the safe side. Not bad, but…