RestKit 0.20.1 将本地 JSON 映射到 Core Data 崩溃

Posted

技术标签:

【中文标题】RestKit 0.20.1 将本地 JSON 映射到 Core Data 崩溃【英文标题】:RestKit 0.20.1 map local JSON to Core Data getting crash 【发布时间】:2013-05-26 01:28:29 【问题描述】:

我正在尝试使用 RestKit 将本地 JSON 映射到我的核心数据实体,因为我正在处理对 API 的身份验证并且已经在使用另一个库来执行此操作,所以我只是将 RestKit 传递给JSON 数据数组(我已经验证我接收正确)。我已经设置了所有基本的必要组件(数据模型/实体、NSManagedObject 类、托管对象上下文等),因为我正在调整我编写的现有应用程序,该应用程序使用 RestKit 访问 RSS 提要并将其映射到核心数据。

根据研究,我似乎应该使用RKManagedObjectMappingOperationDataSource 来完成此操作,并为此调整了我在单元测试中找到的示例:

-(void)performMapping

    FoodTruck *foodTruck = FoodTruck.new;
    RKEntityMapping *mapping = [ObjectMappings FoodTruckArticleMapping];
    RKManagedObjectStore *store = [[FoodTruckDataModel sharedDataModel] objectStore];
    RKManagedObjectMappingOperationDataSource *mappingDS = [[RKManagedObjectMappingOperationDataSource alloc] initWithManagedObjectContext:store.mainQueueManagedObjectContext cache:store.managedObjectCache];
    mappingDS.operationQueue = [NSOperationQueue new];
    RKMappingOperation *operation = [[RKMappingOperation alloc] initWithSourceObject:self.moreStatuses destinationObject:foodTruck mapping:mapping];
    operation.dataSource = mappingDS;
    NSError *error = nil;
    [operation performMapping:&error];
    [mappingDS.operationQueue waitUntilAllOperationsAreFinished];

我的对象映射是在一个单独的映射类中完成的,如下所示:

+(RKEntityMapping *)FoodTruckArticleMapping

    RKEntityMapping *jsonMapping = [RKEntityMapping mappingForEntityForName:@"FoodTruck" inManagedObjectStore:[[FoodTruckDataModel sharedDataModel] objectStore]];
    jsonMapping.identificationAttributes = @[@"tweetID"];

    [jsonMapping addAttributeMappingsFromDictionary:@
 @"text": @"tweet", @"user.screen_name": @"foodTruckName", @"id": @"tweetID", @"created_at": @"timeStamp"];

    return jsonMapping;

我的 FoodTruckDataModel 类如下所示:

+(id)sharedDataModel 
    static FoodTruckDataModel *__sharedDataModel = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^
        __sharedDataModel = [[FoodTruckDataModel alloc] init];
    );

    return __sharedDataModel;


- (NSManagedObjectModel *)managedObjectModel

    return [NSManagedObjectModel mergedModelFromBundles:nil];


-(id)optionsForSQLiteStore

    return @
         NSInferMappingModelAutomaticallyOption: @YES,
         NSMigratePersistentStoresAutomaticallyOption: @YES
         ;


-(void)setup

    self.objectStore = [[RKManagedObjectStore alloc] initWithManagedObjectModel:[self managedObjectModel]];

    [self.objectStore createPersistentStoreCoordinator];

    NSString *path = [RKApplicationDataDirectory()     stringByAppendingPathComponent:@"FoodTruckxxx.sqlite"];
    NSLog(@"Setting up store at %@", path);
    [self.objectStore addSQLitePersistentStoreAtPath:path
                          fromSeedDatabaseAtPath:nil
                               withConfiguration:nil
                                         options:self.optionsForSQLiteStore
                                           error:nil];

    [self.objectStore createManagedObjectContexts];

    self.objectStore.managedObjectCache = [[RKInMemoryManagedObjectCache alloc] initWithManagedObjectContext:self.objectStore.persistentStoreManagedObjectContext];

但是,有些事情没有正确完成,因为我收到了这个核心数据错误:

2013-05-25 19:38:17.867 FoodTrucks[37340:c07] CoreData: error: Failed to call designated initializer on NSManagedObject class 'FoodTruck'

我也遇到了崩溃:

2013-05-25 19:38:17.887 FoodTrucks[37340:4903] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** setObjectForKey: key cannot be nil'

看起来好像它正在对我的数据执行映射操作,但它没有被传递给我的实体和映射信息,从我的log (JSON data erased). 可以看出我不确定我做错了什么,因为它在我使用 RKManagedObjectRequestOperation 之前工作正常。

如果有人有任何建议或帮助,将不胜感激!

【问题讨论】:

【参考方案1】:

第一个问题(也可能是第二个)的原因是:

FoodTruck *foodTruck = FoodTruck.new;

因为您不允许实例化这样的托管对象。相反,您必须使用 NSEntityDescription。您目前拥有的代码不会创建有效的实例,因此当您尝试使用它时会发生坏事。

【讨论】:

谢谢!是的,经过进一步的思考,这似乎是问题所在,因为 NSManagedObjects 的全部意义在于它们是动态的,而且您不会自己实例化它们——我只是不确定将 RKMappingOperation 作为目的地传递什么对象。 虽然,我确实在“核心数据”部分的github.com/RestKit/RestKit/wiki/… 找到了我在 RestKit 的 0.10 到 0.20 升级说明中使用的 FoodTruck *foodTruck = FoodTruck.new; 行;不过,它可能不适用于这种特定情况。

以上是关于RestKit 0.20.1 将本地 JSON 映射到 Core Data 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

将 JSON 键值映射到 RestKit 0.20.1 中的核心数据属性

iOS7 是不是有轻量级 JSON 到对象映射器(不是 RestKit 或 NSJSONSerialization)?

通过 RestKit 将 JSON 的本地 NSString 反序列化为对象(无网络下载)

RestKit:给定 RKObjectMapping、object.class 和 JSON 字符串,如何获取映射对象?

RestKit 无法将 JSON 请求中格式为字符串的日期保存到我的本地数据库

如何使用带有 RKObjectMapping 的 RestKit 0.24 将本地 JSON 字符串映射到对象?