RestKit 0.20 - CoreData: ошибка: не удалось вызвать назначенный инициализатор в классе NSManagedObject

Я столкнулся с новой проблемой, которую, похоже, не могу найти ... Вот мой код RestKit, следуя примеру Twitter Core Data:

//
// RESTKIT
//

// restkit object manager
NSString *baseURL = @"http://test1.website.com";
RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:baseURL]];

// enable activity indicator
[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;

// managed object model
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"AppName" withExtension:@"momd"];
NSManagedObjectModel *managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
// NSLog(@"managed object model: %@", managedObjectModel);

// managed object store
RKManagedObjectStore *managedObjectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:managedObjectModel];
objectManager.managedObjectStore = managedObjectStore;
// NSLog(@"managed object store: %@", managedObjectStore);

// persistent store
NSError *error;
NSString *storePath = [RKApplicationDataDirectory() stringByAppendingPathComponent:@"AppName.sqlite"];
NSPersistentStore *persistentStore = [managedObjectStore addSQLitePersistentStoreAtPath:storePath fromSeedDatabaseAtPath:nil withConfiguration:nil options:nil error:&error];
if (error) {
    NSLog(@"unresolved error %@, %@", error, [error userInfo]);
    abort();
}
// NSLog(@"persistent store coordinator: %@", managedObjectStore.persistentStoreCoordinator);
// NSLog(@"persistent store: %@", persistentStore);

// managed object contexts
[managedObjectStore createManagedObjectContexts];
// NSLog(@"managed object context: %@", managedObjectStore.mainQueueManagedObjectContext);

// managed object cache
managedObjectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:managedObjectStore.mainQueueManagedObjectContext];
// NSLog(@"mangaged object cache: %@", managedObjectStore.managedObjectCache);

//
// entity mapping
//

// album entity mapping
RKEntityMapping *albumEntityMapping = [RKEntityMapping mappingForEntityForName:@"Album" inManagedObjectStore:managedObjectStore];
albumEntityMapping.identificationAttributes = @[ @"identifier" ];
[albumEntityMapping addAttributeMappingsFromDictionary:@{ @"title" : @"title" }];

//
// response descriptor
//

// album response descriptor
[objectManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:albumEntityMapping pathPattern:[NSString stringWithFormat:@"/albums/display/%@/%@", userInfo[@"userID"], userInfo[@"apiKey"]] keyPath:nil statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]];

Я запрашиваю информацию из API через класс UITableViewController:

- (void)loadObjectsFromResourcePath:(NSString *)resourcePath;
{
   [[RKObjectManager sharedManager] getObjectsAtPath:resourcePath parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
        NSLog(@"mapping result: %@", [mappingResult array]);
        [self stopLoading];
    } failure:^(RKObjectRequestOperation *operation, NSError *error) {
        NSLog(@"error: %@", error);
        [self stopLoading];
    }];
}

Однако с этим кодом я получаю следующие ошибки:

2012-12-05 17:08:14.830 AppName Alpha[1310:907] I restkit:RKLog.m:34 RestKit logging initialized...
2012-12-05 17:08:15.107 AppName Alpha[1310:907] resource path: albums/display/102/drrrbSAt6RFLsgHaKiiB6kBIyYRyzxLYinL84Kba
2012-12-05 17:08:15.113 AppName Alpha[1310:907] I restkit.support:RKMIMETypeSerialization.m:115 JSON Serialization class 'RKNSJSONSerialization' detected: Registering for MIME Type 'application/json
2012-12-05 17:08:15.118 AppName Alpha[1310:1603] I restkit.network:RKHTTPRequestOperation.m:141 GET 'http://test1.AppName.com/albums/display/102/drrrbSAt6RFLsgHaKiiB6kBIyYRyzxLYinL84Kba'
2012-12-05 17:08:15.122 AppName Alpha[1310:907] error (null), (null)
2012-12-05 17:08:35.333 AppName Alpha[1310:3e13] I restkit.network:RKHTTPRequestOperation.m:158 GET 'http://test1.AppName.com/albums/display/102/drrrbSAt6RFLsgHaKiiB6kBIyYRyzxLYinL84Kba' (200)
2012-12-05 17:08:35.351 AppName Alpha[1310:1507] CoreData: error: Failed to call designated initializer on NSManagedObject class 'AppName Album' 
2012-12-05 17:08:35.355 AppName Alpha[1310:1507] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<AppName 0x1c579380> valueForUndefinedKey:]: the entity (null) is not key value coding-compliant for the key "Title".'
*** First throw call stack:
(0x39e503e7 0x38ea9963 0x39e500d5 0x371f8d81 0x3276cc1d 0xbf545 0xc00f5 0xc0ab9 0xc44c5 0x32791299 0xb738b 0xb6e5f 0xb7ca5 0xb8343 0xb895b 0x32791299 0xf96ef 0xf8c4b 0x32791299 0x328097f7 0x32c38793 0x32c3c657 0x32c3c7d9 0x3312a7f1 0x3312a684)
libc++abi.dylib: terminate called throwing an exception

Вы можете увидеть возвращенный объект JSON здесь: http://test1.AppName.com/albums/display/102/drrrbSAt6RFLsgHaKiiB6kBIyYRyzxLYinL84Kba


person Michael Rose    schedule 05.12.2012    source источник


Ответы (2)


Это указывает на то, что была предпринята попытка создать объект без вызова соответствующего инициализатора Core Data, что, вероятно, означает, что вы получаете экземпляр RKObjectRequestOperation вместо RKManagedObjectRequestOperation.

Я подозреваю, что дескриптор ответа не соответствует URL-адресу, из-за чего он выбирает неправильный тип операции запроса объекта. Вы можете проверить это, поставив точку останова в appropriateObjectRequestOperationWithObject:method:path:parameters: в строках, которые читаются:

NSArray *matchingDescriptors = RKFilteredArrayOfResponseDescriptorsMatchingPath(self.responseDescriptors, requestPath);
BOOL containsEntityMapping = RKDoesArrayOfResponseDescriptorsContainEntityMapping(matchingDescriptors);
BOOL isManagedObjectRequestOperation = (containsEntityMapping || [object isKindOfClass:[NSManagedObject class]]);

Эта логика отвечает за выбор типа создаваемой операции. Убедитесь, что matchingDescriptors содержит ожидаемый дескриптор ответа, а затем проверьте значения следующих двух логических значений. Я предполагаю, что RKFilteredArrayOfResponseDescriptorsMatchingPath не возвращает то, что вы ожидаете.

person Blake Watters    schedule 05.12.2012
comment
что это за класс? также, что возвращает ошибку (null, null) при первом запросе GET. Кроме того, почему выходят два запроса? :) - person Michael Rose; 06.12.2012
comment
appropriateObjectRequestOperationWithObject:method:path:parameters: находится в RKObjectManager. Обратите внимание, что не поступают 2 запроса. Первое сообщение журнала предназначено для отправки, а второе, которое включает в себя (200), находится в ответе. Это сообщение об ошибке (null, null) поступает из NSLog в вашем блоке завершения ошибки. - person Blake Watters; 06.12.2012
comment
Я принудительно выполнил операцию RKManagedObjectRequestOperation, и она работает. Мне придется вернуться завтра, чтобы увидеть, в чем корень проблемы. Ошибка (null, null) исходит не от меня. Я закомментировал блок даже для двойной проверки. - person Michael Rose; 06.12.2012
comment
Как бы то ни было, это было полезно для меня с той же проблемой (CoreData + RestKit, получение объектов, как указано выше). Я смог исправить это из-за этого описания для отладки. Спасибо! На самом деле моя ошибка заключалась в том, что в одном случае использовалось два "/". - person mr.andy.peters; 16.12.2012
comment
Я значительно улучшил вывод ошибок, когда дескрипторы ответа не совпадают. Если вы выходите из системы из-за ошибки NSError, возвращаемой при неудачном сопоставлении, NSLocalizedFailureReasonErrorKey теперь содержит подробное описание того, как сопоставление не удалось. - person Blake Watters; 17.12.2012
comment
Новый вопрос @BlakeWatters, все работает, как ожидалось, когда / article (статьи отображаются и помещаются в CoreData), но GET для / article / 1 снова имеет ту же проблему. Я прошел, как указано выше. Когда я устанавливаю точки останова (начиная с) 398 в RKObjectManager.m, я обнаруживаю, что у него есть соответствующие дескрипторы. Но я заметил, что после строки 405 объект managedObjectContext равен нулю, поэтому условие if в строке 407 не выполняется. (RESTKit 0.20.0pre4). - person mr.andy.peters; 17.12.2012
comment
Этот этап отладки позволил мне продолжить работу после нескольких дней зависания. Спасибо andy9d за ваш комментарий. Я увидел, что в моем events.json не было /. добавление одного позволило моему GET вернуться с 200 OK. Теперь перейдем к отладке сопоставления. - person Nungster; 28.12.2012
comment
Я хотел бы добавить, что эта ошибка также может возникнуть, если вы инициализируете RKResponseDescriptor с RKObjectMapping вместо RKEntityMapping. Я слепо следовал инструкциям и не понимал, что мне не нужно создавать отдельный RKObjectMapping для моих дескрипторов запроса и ответа. - person oohaba; 29.03.2013
comment
Как и многие другие вышеупомянутые, это произошло, когда путь на RKResponseDescriptor не совпадал. URL-адрес похож на /abc/objects, но я включил в дескриптор только "/ objects". Спасибо!! - person James Skidmore; 28.09.2013

Прочитали документацию по классам для RKObjectManager, в которой разъясняется обработка сетевой обработки базового URL-адреса AF. Если бы я сначала прочитал это, я бы сэкономил некоторое время, а также избавился бы от нерелевантных комментариев относительно путей в примерах RestKit.

Возникли проблемы с сопоставлением сочетания сопоставлений объектов и сущностей, включая ряд сопоставлений объектов с нулевым ключевым путем и другим URL-адресом, и нашел этот ответ очень полезным для определения причины описанной ниже проблемы, которая, возможно, способствовала возникновению аналогичных проблем у других.

person ptc    schedule 08.12.2013