Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I decode an object when original class is not available?

I have an iOS 7 application that saves a custom object to app's iCloud Docs folder as a file. For this, I make use of NSCoding protocol.

@interface Person : NSObject <NSCoding>      @property (copy, nonatomic) NSString *name     @property (copy, nonatomic) NSString *lastName  @end 

Object serialization works perfectly in iOS 7 version of the app:

  1. initWithCoder and encodeWithCoder

  2. [NSKeyedArchiver archivedDataWithRootObject:person]

  3. person = NSKeyedUnarchiver unarchiveObjectWithData:(NSData *)theData]

But I need to move this app to iOS 8, and this class will be coded in swift and 'renamed' for this new iOS 8 version of the app.

class PersonOldVersion: NSObject, NSCoding {     var name = ""     var lastName = "" } 

When I try to unarchive the object I got the following error:

*** Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: '*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (Person)' 

I already tried renaming swift class 'PersonOldVersion' to original class name ('Person') but still fails.

How can I decode an object which original class isn't available?

like image 963
Aнгел Avatar asked Aug 25 '14 18:08

Aнгел


2 Answers

This might be another solution, and it's what I did (since I didn't use Swift at that time).

In my case, I archived an object of class "City" but then renamed the class to "CityLegacy" because I created a completely new "City" class.

I had to do this to unarchive the old "City" object as a "CityLegacy" object:

// Tell the NSKeyedUnarchiver that the class has been renamed [NSKeyedUnarchiver setClass:[CityLegacy class] forClassName:@"City"];  // Unarchive the object as usual NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSData *data = [defaults objectForKey:@"city"]; CityLegacy *city = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 
like image 151
Ferran Maylinch Avatar answered Oct 04 '22 05:10

Ferran Maylinch


If the name of the class in Objective-C is important, you need to explicitly specify the name. Otherwise, Swift will provide some mangled name.

@objc(Person) class PersonOldVersion: NSObject, NSCoding {     var name = ""     var lastName = "" } 
like image 45
newacct Avatar answered Oct 04 '22 06:10

newacct