Search code examples
iosswiftnskeyedunarchiver

How to unarchive custom object to something other than custom class in Swift


I have an object where we used NSKeyedArchiver to archive as class Foo

Then I changed the target name from Apple to Orange. And it went into production and users started crashing on startup. But not all. And logs point to NSKeyedUnarchiver

I went and grabbed the archived Foo file from when the target was called Apple and when it was called Orange and converted to xml so I could read it. The main and only difference (I think) is that the classname key is Apple.Foo and Orange.Foo respectively.

How can I get one of the archived files and check it's archived class name?

If I do NSKeyedUnarchiver.unarchiveObject(withFile: path) as? Foo it will crash.

Ideally I'd so something like:

let object = NSKeyedUnarchiver.unarchiveObject(withFile: path) as? [String : Any] 
let name = object!["classname"]!
if name == "Apple.Foo" {
    //delete the cache and let it rebuild
}

But obviously it doesn't work like this. Any ideas on how I can check that I have a corrupted file and get it deleted without the app crashing?

Thanks for the help!


Solution

  • Over the last few days I learned that you can set two different class names for the unarchiver at the same time and they'll both work:

    NSKeyedUnarchiver.setClass(Foo.classForKeyedUnarchiver(), forClassName: "Apple.Foo")
    NSKeyedUnarchiver.setClass(Foo.classForKeyedUnarchiver(), forClassName: "Orange.Foo")
    

    Now it doesn't matter what classname the file actually has at the time of unarchiving.