Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSInvalidUnarchiveOperationException cannot decode object error in Apple Watch extension

I've got a user object that I need to store in NSUserDefaults and share with an iOS 8 extension app (Watchkit). In the main container app, I can encode and decode the object without any problem. However, when I try to retrieve the stored user object in the Extension, I get a "'NSInvalidUnarchiveOperationException', reason: '*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class" error.

As far as I can see NSCoding has been implemented correctly in the object (and I'm able to encode and decode the object in the 'main' app).

Code in 'Container' app to store user object.

//Store user data in NSUserDefaults
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.mygroup"];

SFUserAccount *user = [SFUserAccountManager sharedInstance].currentUser;

NSData *userEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:user];
[defaults removeObjectForKey:@"SF User Acct1"]; //remove any old values
[defaults setObject:userEncodedObject forKey:@"SF User Acct1"];

[defaults synchronize];
SFUserAccount *decodedUser =  [NSKeyedUnarchiver unarchiveObjectWithData:userEncodedObject];

The last line above to perform a test decode in the main app works fine.

The code to retrieve from NSUserDefaults and decode in the extension target is below.

NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.mygroup"];
    NSData *archivedUser = [defaults objectForKey:@"SF User Acct1"];



    if (archivedUser){
        SFUserAccount *user =  [NSKeyedUnarchiver unarchiveObjectWithData:archivedUser];
    }

In the extension code, I get a "'NSInvalidUnarchiveOperationException', reason: '*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class"

Any suggestions as to where I should start looking? The app compiles fine which leads me to believe that the required frameworks have been included in the Extension target.

like image 315
YogiBotics Avatar asked Nov 30 '14 10:11

YogiBotics


1 Answers

For your WatchKit Extension to be able to decode SFUserAccount objects, it needs to understand the SFUserAccount class. To enable this, it should be added to your WatchKit Extension.

  1. Click on your project name in the Project Navigator, at the top of the left column in Xcode. (Press Cmd-1 to show the Project Navigator if it is hidden.
  2. Click to highlight the name of your WatchKit Extension on the left of the main window, under 'Targets'. (NOTE: highlight your WatchKit Extension, not the WatchKit App.
  3. Select 'Build Phases' in the items across the top.
  4. Next to 'Compile Sources', use the disclosure triangle to view the section if it is not already visible.
  5. Click the '+' at the bottom of the section to add a new source.
  6. From the list, select the .m file for the Class you need to add (in this case, the SFUserAccount.m file).
  7. Click 'Add'.
  8. Build and run.
like image 165
Duncan Babbage Avatar answered Sep 22 '22 21:09

Duncan Babbage