Невозможно декодировать объект класса Employee для ключа (NS.object.0); класс может быть определен в исходном коде или библиотеке, которая не связана

Я пытаюсь передать массив объектов iPhone «Сотрудник» на Apple Watch путем сериализации массива:

NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:employees];

и десериализуем его, как на стороне Watch:

NSMutableArray *employees = [NSKeyedUnarchiver unarchiveObjectWithData:encodedObject];

Это класс «Сотрудник»:

@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

Нужно ли мне вносить какие-либо изменения на стороне часов, чтобы исправить эту ошибку?


person user2189878    schedule 04.05.2016    source источник
comment
Похоже, код, выполняющий декодирование, не знает о классе Employee. Встраивается ли это в часовую сторону?   -  person trojanfoe    schedule 04.05.2016
comment
да. Я должен показать список сотрудников на часах   -  person user2189878    schedule 04.05.2016
comment
убедитесь, что класс Employee добавлен в цель Watch и соответствует протоколу NSCoding.   -  person Surya Subenthiran    schedule 04.05.2016
comment
Возможный дубликат Могу ли я кодировать подкласс NSManagedObject?   -  person    schedule 04.05.2016
comment
Вы понимаете, что управляемый объект не может быть передан другому потоку, контексту управляемого объекта или устройству?   -  person    schedule 04.05.2016


Ответы (3)


так что у меня была точно такая же проблема, и ответ прост, но немного сложно найти самому.

Вам просто нужно использовать:

  • NSKeyedArchiver.setClassName("Employee", for: Employee.self)
    перед сериализацией
  • NSKeyedUnarchiver.setClass(Employee.self, forClassName: "Employee")
    перед десериализацией

везде, где нужно.

Похоже, расширения iOS префикс имени класса с именем расширения.

person teriiehina    schedule 11.05.2016
comment
Спасибо. Удовольствие от обновления большого приложения с objc до Swift. - person Klajd Deda; 26.10.2017

Для меня это происходило в моем расширении Today. Исправлено добавление @objc (MyExampleClass) перед объявлением.

@objc(MyExampleClass)
open class MyExampleClass {
....
}
person Stefan S    schedule 23.08.2018

Ответ teriiehina помог мне частично добраться туда; Я мог заархивировать и разархивировать на чистые устройства, но все равно получал указанную выше ошибку при попытке разархивировать существующий архив.

В конце концов я нашел этот вопрос: Добавлен настраиваемый фреймворк, теперь Swift может не разархивировать данные, на которые пользователь ответил сам:

При перемещении DemoNote из приложения в платформу имя модуля изменилось, а это означало, что NSKeyedUnarchiver не смог найти экземпляры заархивированного класса из-за несоответствия имени.

Его решение по добавлению имени старого проекта к строке className (например, если проект назывался "CompanyDirectory", то с использованием "CompanyDirectory.Employee", а не просто "Employee") было тем, что мне нужно, чтобы иметь возможность разархивировать мои данные из моей модели, которые были перемещены в новую -созданный связанный Framework.

person tomg    schedule 12.04.2018
comment
Вы правы, архивирование / разархивирование в одном контексте (например, в одном приложении) работает хорошо, ничего не делая. У меня возникла проблема с архивированием объекта в общий монтажный стол из App1 и его разархивированием, получая данные с монтажного стола в App2. Для этого варианта использования мне пришлось установить класс, как сказала @teriiehina. - person DSoldo; 28.11.2019