3

We've got a Swift class which inherits from NSObject and implements NSCoding. We need to change the name of the class in code and in the archives on disk. Fortunately, we don't need to retain the data. Wiping the cached files and returning default data will be fine. The trouble is detecting when it fails and handling it appropriately.

Ok, to start with the data is written out like this (ignore liberties with force unwrapping etc. it's just to keep the question concise):

let someObject: [Int: MyClass] = ...
let data = NSKeyedArchiver.archivedData(withRootObject: someObject)
try! data.write(to: someUrl, options: .atomic)

This works fine. Our existing method of decoding is this (again, our code is safer in practice):

let someObject = NSKeyedUnarchiver.unarchiveObject(withFile: someUrl.path)! as! [Int: MyClass]

Now, when we rename our class, we are going to have to deal with the cases where it fails to decode. With NSKeyedUnarchiver, you can set a delegate which will have a method called if decoding fails. Before changing it, I wanted to re-write our existing decoder to make sure it can decode as is before I make any changes. Unfortunately, it can't. Here is what we've got:

let fileData = fileManager.contents(atPath: fileUrl.path)!
let unarchiver = NSKeyedUnarchiver(forReadingWith: fileData)
guard let myObject = try! unarchiver.decodeTopLevelObject() as? [Int: MyClass] else {
  return [Int: MyClass]()
}

Now, I didn't expect any issues with this. However, the call to decodetopLevelObject() fails every time, simply returning nil (it's definitely not the cast that's the problem). I have no idea why. The documentation for this is effectively non-existent. There is a similar call which is decodeObject(), but that also fails for no obvious reason. I've tried setting the delegate and implementing the method, but it never gets called.

Where are we going wrong?

Dale Myers
  • 2,703
  • 3
  • 26
  • 48

1 Answers1

0

Try using decodeObject(forKey:) with NSKeyedArchiveRootObjectKey or similar API.

MaddTheSane
  • 2,981
  • 24
  • 27