Cannot decode object of class Employee for key (NS.object.0); the class may be defined in source code or a library that is not linked
Asked Answered
H

3

12

Im trying to pass an array of 'Employee' objects iPhone to Apple Watch by serializing the array :

NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:employees];

and unserializing it as on the Watch side:

NSMutableArray *employees = [NSKeyedUnarchiver unarchiveObjectWithData:encodedObject];

This is the 'Employee' class:

@interface Employee : NSManagedObject
@property (nonatomic, retain) NSNumber * employeeID;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * age;
@property (nonatomic, retain) NSString * address;
@property (nonatomic, retain) NSString * designation;
@property (nonatomic, retain) NSString * teamName;
@property (nonatomic, retain) NSString * gender;
@property (nonatomic, retain) NSNumber * dateOfJoining;
@end

Do I have to do any changes on the Watch side to fix this error?

Harilda answered 4/5, 2016 at 12:42 Comment(5)
It looks like the code doing the decoding doesn't know about the Employee class. Is it being compiled into the watch side?Antipater
Yes. I have to show list of Employees on the watchHarilda
make sure that Employee class added in the Watch target and it conforms NSCoding protocol.Reformer
Possible duplicate of Can I encode a subclass of NSManagedObject?Tincher
Do you realize that a managed object can't be passed to another thread, managed object context, or device?Tincher
P
40

so I just had that exact same problem and the answer is simple but a little hard to find by oneself.

You simply have to use:

  • NSKeyedArchiver.setClassName("Employee", for: Employee.self)
    before serializing
  • NSKeyedUnarchiver.setClass(Employee.self, forClassName: "Employee")
    before deserializing

wherever needed.

Looks like iOS extensions prefix the class name with the extension's name.

Phytopathology answered 11/5, 2016 at 12:35 Comment(1)
Thank You. The fun of upgrading large app from objc to swift.Relentless
A
12

For me it was happening in my Today extension. What fixed it was adding @objc(MyExampleClass) before the declaration.

@objc(MyExampleClass)
open class MyExampleClass {
....
}
Abisha answered 23/8, 2018 at 11:3 Comment(0)
M
2

teriiehina's answer got me part of the way there; I could archive and unarchive to clean devices but still got the above error when trying to unarchive an existing archive.

Eventually I found this question: Added a custom framework, now Swift can't unarchive data, which the user answered himself:

Moving DemoNote from the app to a framework did change the module name, which meant that NSKeyedUnarchiver couldn't find instances of the archived class due to a name mismatch.

His solution of prefixing the old project's name to the className string (e.g. if the project was called "CompanyDirectory" then using "CompanyDirectory.Employee" as opposed to just "Employee") was what I needed to be able to unarchive my data from my model which had been moved into a newly-created linked Framework.

Mcclean answered 12/4, 2018 at 12:30 Comment(1)
You're right, archive/unarchive inside the same "context" (like inside the same app) works well without doing nothing. I had the problem archiving an object into the general pasteboard from App1 and unarchiving it getting the data from the pasteboard in App2. For this usecase I had to set the class as @Phytopathology said.Mapping

© 2022 - 2024 — McMap. All rights reserved.