3

After upgrading to Xcode9, we get a crash/warning (looks like a warning but behaves like a crash) when we try to encode a mock object using [NSKeyedArchiver archivedDataWithRootObject:mockObject]:

Attempting to archive Swift class 'Foo.MockUser' with mangled runtime 
name '_TtCC13Foo27Bar8MockUser'. The runtime name for this class is 
unstable and may change in the future, leading to non-decodable data.

Is there any way to disable or work around this?

mattliu
  • 823
  • 12
  • 28
  • Did you check this link https://stackoverflow.com/questions/45751848/how-to-save-a-generic-custom-object-to-userdefaults? – trungduc Nov 03 '17 at 17:00

1 Answers1

4

Since the warning refers to Swift, I suppose your mock is written in Swift. In that case you need to add an @objc attribute with a name to it, just as the warning suggests.

If this is the first version of your app (i.e. it is not an update to an already published app), it can be just a prefixed name like this:

@objc(ABCDEFMockUser)class MockUser: NSObject, NSCoding {
   ...
}

*note that "ABCDEF" here is anything you want, but "MockUser" has to match your class name.

But if there is a live version of your app already in the wild and you don't want it to crash after update, you will need a special name there. This name is written in the Xcode's warning itself. In your case it is:

@objc(_TtCC13Foo27Bar8MockUser)class MockUser: NSObject, NSCoding {
   ...
}

Actually the easiest way is to just click the yellow warning sign and hit "Fix" in the very first Xcode's suggestion saying "For compatibility with existing archives use...". That's it.

Vitalii
  • 4,267
  • 1
  • 40
  • 45
  • "Actually the easiest way is to just click the yellow warning sign" - the problem is that we were seeing this with a red error. I do agree that this should only be a warning, but it's behaving like a crash. I have not yet tested this on Xcode 9.1 or later - hopefully it's fixed in the newer versions. – mattliu Dec 11 '17 at 17:12
  • @mattliu could that be because your archiving code is in Obj-C? In my case I had the code that does archiving/unarchiving and the object itself all in Swift. – Vitalii Dec 11 '17 at 17:33