RestKit 在映射或实际插入 CoreData DB 之前比较本地对象和远程对象
Posted
技术标签:
【中文标题】RestKit 在映射或实际插入 CoreData DB 之前比较本地对象和远程对象【英文标题】:RestKit comparing local objects and remote objects before mapping or actually inserting into CoreData DB 【发布时间】:2014-06-20 10:25:15 【问题描述】:所以我开始在 RestKit 中实现我的第二个项目,前一个非常简单,只需从远程服务中提取内容并填写我的核心数据 db。在当前应用程序中,我正在开发同步功能,因此我想在插入之前验证内容,即将本地存储中的对象与我从远程服务获取的对象进行比较。
我正在阅读 this thread 并发现我可以实现这样的目标。所以我将这两种方法添加到我的模型中。我知道只有一种方法就足够了,但问题在于这两种功能。
@implementation News
@dynamic title;
@dynamic desc;
@dynamic time;
@dynamic category;
@dynamic content;
- (BOOL)validateValue:(inout __autoreleasing id *)ioValue forKeyPath:(NSString *)inKeyPath error:(out NSError *__autoreleasing *)outError
return NO;
- (BOOL)validateTitle:(id *)ioValue error:(NSError **)outError
return NO;
实体映射代码,
RKEntityMapping *userMapping = [RKEntityMapping mappingForEntityForName:NSStringFromClass(theClass) inManagedObjectStore:objectManager.managedObjectStore];
userMapping.performsKeyValueValidation = YES;
userMapping.discardsInvalidObjectsOnInsert = YES;
所以我认为,每当一个对象被映射或被覆盖时,这个方法就会被触发。所以 self 将包含当前对象,而 *ioValue 将包含将插入或不插入的新值,我的结论是否正确??
现在在我的应用 self.title 中触发该方法并且 *ioValue 包含 same value 即 来自服务和 self.title 的新值 不包含本地存储中的旧值(可能是对数据库的更改已经发生:( )。另外,如果我从这个方法返回 No 记录仍然被映射,这不应该发生吗?
对此问题的任何见解都会有很大帮助。我即将在不使用 RestKit 的情况下从头开始。
【问题讨论】:
【参考方案1】:如果你总是从验证方法中返回NO
,那么你应该总是在映射后得到空对象。如果不是这样,那么您需要调查一个基本的 KVC 验证问题。
如果您使用的是普通对象映射,那么空对象也可以,并且会始终返回给您。
如果您使用实体映射,则可以将一些属性设置为强制(非可选),然后在映射上配置 discardsInvalidObjectsOnInsert
,这样当您不更新某些值时,任何无效对象都将被丢弃(而不是比保存)。
所以我认为每当一个对象被映射或被覆盖时,这个方法就会被触发。所以
self
将包含当前对象,*ioValue
将包含将插入或不插入的新值
正确。虽然这仅适用于具有唯一标识符的实体映射,因为这允许 RestKit 找到原始值。
【讨论】:
我已将 discardsInvalidObjectsOnInsert 设置为 YES,并且已设置唯一标识符。discardsInvalidObjectsOnInsert
要求您教导实体有效的含义,您可以覆盖validateForInsert:
或设置属性要求。跟踪日志应告诉您何时找到现有对象以及每个属性是否与现有值匹配或已更改。在将更改保存到数据存储之前运行 KVC 验证。以上是关于RestKit 在映射或实际插入 CoreData DB 之前比较本地对象和远程对象的主要内容,如果未能解决你的问题,请参考以下文章
RestKit 对象映射 POST 响应,“CoreData:错误:在 NSManagedObject 类映射操作上调用指定初始化程序失败”