ResKit:临时 NSManagedObjects

Posted

技术标签:

【中文标题】ResKit:临时 NSManagedObjects【英文标题】:ResKit: temporary NSManagedObjects 【发布时间】:2013-10-02 08:54:45 【问题描述】:

经过长时间的研究,我正在写这篇文章,但我真的很难找到解决我问题的最佳方法。

我对 resKit 和 CoreData 都很陌生...无论如何,我正在映射并在 CoreData 中保存我从 Web 服务接收到的 JSON。

这里有一些代码:

//ResKit and Core Data initialization here ... //Initialization RKObjectManager RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@"http://http://www.myWebService.com"]]; objectManager.managedObjectStore = managedObjectStore; [RKObjectManager setSharedManager:objectManager]; //Categories Mapping and descriptor RKEntityMapping *categoriesMapping = [RKEntityMapping mappingForEntityForName:@"XNCategory" inManagedObjectStore:managedObjectStore]; [categoriesMapping addAttributeMappingsFromDictionary:@ @"id": @"idCategory", @"desc": @"desc", @"idFam":@"idFam"]; categoriesMapping.identificationAttributes = @[ @"idCategory" ]; RKResponseDescriptor *categoriesDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:categoriesMapping method:RKRequestMethodGET pathPattern:@"getData.asp" keyPath:@"categories" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]; //Families Mapping and descriptor RKEntityMapping *familiesMapping = [RKEntityMapping mappingForEntityForName:@"XNFamily" inManagedObjectStore:managedObjectStore]; [familiesMapping addAttributeMappingsFromDictionary:@ @"id": @"idFam", @"desc": @"desc"]; familiesMapping.identificationAttributes = @[ @"idFam" ]; RKResponseDescriptor *familiesDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:familiesMapping method:RKRequestMethodGET pathPattern:@"getData.asp" keyPath:@"families" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]; //Relation between the 2 mapping NSEntityDescription *categoryEntity = [NSEntityDescription entityForName:@"XNCategory" inManagedObjectContext:[managedObjectStore mainQueueManagedObjectContext]]; NSRelationshipDescription *userRelationshipFrom = [categoryEntity relationshipsByName][@"family"]; RKConnectionDescription *connectionUserMessageFrom = [[RKConnectionDescription alloc] initWithRelationship:userRelationshipFrom attributes:@ @"idFam": @"idFam" ]; [categoriesMapping addConnection:connectionUserMessageFrom]; //Finally add the descriptor to the object manager [objectManager addResponseDescriptor:categoriesDescriptor]; [objectManager addResponseDescriptor:familiesDescriptor];

在另一个视图控制器中,当我需要下载所有数据时,我只是这样做:

[[RKObjectManager sharedManager] getObjectsAtPath:@"getData.asp" parameters:@kAuthKeyName : kAuthKeyValue success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) //Success block failure:^(RKObjectRequestOperation *operation, NSError *error) //Failure Block ];

此代码正确下载并自动保存到CoreData中的持久存储中,保留实体之间的关系。

现在我的问题是:有什么方法可以避免这种自动保存吗?因为我需要处理从webService检索到的数据,只有在我决定的时候才保存。

我发现这篇文章非常有用,或者至少给了我一个很好的开始研究的输入:Best practice for temporary objects in RestKit with Core Data,但这是 2012 年的一篇文章,我不知道是否发生了变化,或者现在是否有更好的解决方案。

换句话说,我需要的是一种允许使用 ResKit 进行映射的方法,因此,所有接收到的数据都将根据我创建的所有 NSRelationshipDescription 进行正确的实体映射,并且手动管理保存到持久存储。

非常感谢您的耐心和帮助。

【问题讨论】:

【参考方案1】:

一般来说,您链接到的答案仍然有效。 RestKit 没有添加对映射完成后不保存上下文的特殊支持(它仍然是自动完成的)。不过,RestKit 创建和管理 Core Data 的方式已经改变。您仍然可以在 Core Data 之外创建对象,然后在准备好保存时将它们映射到托管对象中。试图篡改由 RestKit 创建的 Core Data 设置可能会在未来(如果不是立即)导致您出现问题,并且维护 2 个不同的持久存储可能比在 Core Data 之外准备数据然后在准备好时将其导入更复杂保存。

【讨论】:

所以,如果我需要手动保存到 CoreData,您的建议是使用“NSMutableDictionary”或“NSObjects”映射方法(如链接中指定)然后保存到 CoreData ?在这种情况下,我将不得不“手动”管理关系,但如果这是正确且更快的方式,我会接受您的回答。 就个人而言,我会重新审视您为什么要延迟保存,因为它会增加数据丢失的风险。如果必须,那么更快(风险更低)的开发路线确实是映射到字典/NSObject,然后转换为 Core Data(您的 Core Data 模型类可以有方法来促进这一点)。 如果我没记错的话,ResKit 从 webService 读取 JSON,映射到 NSManagedObjects 并保存在 coreData 中,自动执行如下操作:更新现有记录,删除不再存在的记录并插入新记录.如果这是正确的,我的问题是当 JSON 以差异模式更新(服务器端)并且每次都没有返回所有记录时:我需要“手动”执行这些操作并在所有操作完成后执行保存到核心数据。如果我说错了,请纠正我。 RestKit 只会在您配置它时删除对象。此外,根据您的配置方式,它可能会从关系中删除项目。最后,你真的应该问你真正的问题——你不应该问你认为什么可以解决你的问题(尽管你应该把它加到你真正问题的末尾)...... 这只是一个例子,我还处于 ResKit 的研究阶段,我只是想象了一个可以使用我提出的解决方案的例子。不管怎样,现在一切都清楚多了,我真的非常非常感谢你!

以上是关于ResKit:临时 NSManagedObjects的主要内容,如果未能解决你的问题,请参考以下文章

为啥我们在 NSManagedObject 中需要临时 ID

如何在应用程序退出时正确删除“临时”NSManagedObject

NSManagedObject 的 managedObjectContext 属性为 nil

RESKit:无响应描述符

RESKit:创建了重复的对象

Reskit - 映射到数组