【发布时间】:2016-04-30 23:07:09
【问题描述】:
总结
我的问题是我想在我的基于 Core Data 的 iOS 项目中删除几乎重复的内容,该项目使用 Ensembles 与 iCloud 同步。
- 与 iCloud 的同步在我的应用程序中基本运行良好。
- 问题是当用户在其持久存储被 Ensembles(连接到 iCloud)窃取之前在多个设备上创建类似对象时。
- 这会产生近乎重复的内容,这实际上是正确的。
- 我删除这些重复项的方法似乎不起作用。
详细问题
用户可以在连接到 iCloud 之前在不同的设备上创建NSManagedObjects。假设他有一个名为Car 的NSManagedObject 与名为Person 的NSManagedObject 具有“To One”关系,而后者与Car 具有“To Many”关系。这看起来像这样:
好的,假设用户有两个设备,他在每个设备上创建了两个NSManagedObjects。一个名为“Audi”的Car 和一个名为“Raphael”的Person。两者都是通过关系联系在一起的。在另一台设备上,他创建了一个名为“BMW”的Car 和另一个名为“Raphael”的Person。也相互连接。现在用户在每台设备上都有两个相似的对象:两个Person 对象都名为“Raphael”。
我的问题是,用户在同步后最终会在每台设备上拥有两个名为“Raphael”的 Person 对象。
这实际上是正确的,因为当用户窃取他的持久存储时,对象会获得它们的唯一标识符(以识别 Ensembles 中的对象)。对象实际上是不同的。但这是我想要解决的问题。
我的方法
我实现了这个委托方法并删除了 reparationContext 中的重复项。
- (BOOL)persistentStoreEnsemble:(CDEPersistentStoreEnsemble *)ensemble
shouldSaveMergedChangesInManagedObjectContext:(NSManagedObjectContext*)savingContext
reparationManagedObjectContext(NSManagedObjectContext *)reparationContext {
[reparationContext performBlockAndWait:^{
// Find duplicates
// Change relationships and only use the inserted Person object (the one from iCloud)
// Delete local Person object
[reparationContext save:nil];
}
return YES;
}
基本上,这似乎在合并来自第一台设备的数据的第二台设备上运行良好。但不幸的是,即使在reparationContext中删除了本地人,它似乎仍然同步到iCloud。
这会导致状态中断,因为第一台设备随后还会合并来自第二台设备的更改并再次替换已在第二台设备上删除的人员。稍后进行一些同步,该人最终在汽车关系中丢失,并且应用程序引发同步错误。
重现问题的步骤
-
第 1 步(设备 1)
- 创建对象
- 数据:汽车“Audi”->人“Raphael(设备 1)”
-
第 2 步(设备 2)
- 创建对象
- 数据:汽车“BMW” -> 人物“Raphael(设备 2)”
-
第 3 步(设备 1)
- 从存储中获取数据
- 连接到 iCloud
- 向 iCloud 发送数据
- 数据:汽车“Audi” -> 人“Raphael(设备 1)”
-
第 4 步(设备 2)
- 从存储中获取数据
- 连接到 iCloud
- 从 iCloud 合并数据
- 将设备 2 中的本地人员替换为设备 1 中的插入人员
- 从设备 2 中删除本地人员
- 向 iCloud 发送数据
- 数据:
汽车“奥迪”-> 人“拉斐尔(设备 1)”
汽车“宝马”-> 人“拉斐尔(设备 1)”
-
第 5 步(设备 1)
- 从 iCloud 合并数据
- 将设备 1 中的本地人员替换为设备 2 中的插入人员(这不应该发生)
- 从设备 1 中删除本地人员(这不应该发生)
- 向 iCloud 发送数据
- 预期数据:
汽车“奥迪”-> 人“拉斐尔(设备 1)”
汽车“宝马”-> 人“拉斐尔(设备 1)” - 实际数据:
汽车“奥迪” -> 人“拉斐尔(设备 2)”
汽车“BMW”-> 人“Raphael(设备 2)”
实际上本地人对象“Raphael (Device 2)”在第 4 步中被删除,但它似乎仍被发送到 iCloud,因为在第 5 步中它作为插入在savingContext.insertedObjects 中从shouldSaveMergedChangesInManagedObjectContext 弹出委托方法。
据我所知,Ensembles 首先从 iCloud 中提取更改,通过委托方法询问用户是否一切都如预期的那样,然后合并到持久存储中,并在合并后将增量发送到 iCloud。
我做错了吗?或者这是一个 Ensembles 错误?
【问题讨论】:
标签: ios core-data synchronization icloud ensembles