概括
我的问题是,我想在使用Ensembles与 iCloud 同步的基于 Core Data 的 iOS 项目中去除几乎重复的内容。
- 与 iCloud 的同步在我的应用程序中运行良好。
- 问题是当用户在他的持久存储被 Ensembles(连接到 iCloud)窃取之前在多个设备上创建类似的对象时。
- 这会产生近乎重复的事实,这实际上是正确的。
- 我删除这些重复项的方法似乎不起作用。
详细问题
用户可以NSManagedObjects
在连接到 iCloud 之前在不同的设备上创建。假设他有一个NSManagedObject
名称,该名称与一个名称Car
具有“对一个”关系,而该名称与一个NSManagedObject
名称Person
具有“对多”关系Car
。这看起来像这样:
好的,假设用户有两个设备,他NSManagedObjects
在每个设备上创建了两个。一个Car
叫“奥迪”,一个Person
叫“拉斐尔”。两者都是通过关系联系在一起的。在另一台设备上,他创建了一个Car
名为“BMW”和另一个Person
名为“Raphael”的设备。也相互连接。现在用户在每台设备上都有两个相似的对象:两个Person
对象都名为“Raphael”。
我的问题是,用户在同步后最终会Person
在每台设备上拥有两个名为“Raphael”的对象。
这实际上是正确的,因为当用户窃取他的持久存储时,对象会获得它们的唯一标识符(以识别 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)
- 创建对象
- 数据:汽车“奥迪”-> 人“拉斐尔(设备 1)”
第 2 步(设备 2)
- 创建对象
- 数据:汽车“BMW”-> 人“Raphael(设备 2)”
第 3 步(设备 1)
- 来自商店的水蛭数据
- 连接到 iCloud
- 将数据发送到 iCloud
- 数据:汽车“奥迪”-> 人“拉斐尔(设备 1)”
第 4 步(设备 2)
- 来自商店的水蛭数据
- 连接到 iCloud
- 合并来自 iCloud 的数据
- 将设备 2 中的本地人员替换为设备 1 中的插入人员
- 从设备 2 中删除本地人
- 将数据发送到 iCloud
- 数据:
汽车“Audi” -> 人“Raphael(设备 1)”
汽车“BMW” -> 人“Raphael(设备 1)”
第 5 步(设备 1)
- 合并来自 iCloud 的数据
- 将设备 1 中的本地人员替换为设备 2 中的插入人员(这不应该发生)
- 从设备 1 中删除本地人(这不应该发生)
- 将数据发送到 iCloud
- 预期数据:
汽车“Audi” -> 人“Raphael(设备 1)”
汽车“BMW” -> 人“Raphael(设备 1)” - 实际数据:
汽车“Audi” -> 人物“Raphael(设备 2)”
汽车“BMW” -> 人物“Raphael(设备 2)”
实际上,本地人员对象“Raphael (Device 2)”在第 4 步中被删除,但它似乎仍被发送到 iCloud,因为在第 5 步中它作为委托方法 savingContext.insertedObjects
的插入弹出。shouldSaveMergedChangesInManagedObjectContext
据我了解,Ensembles 首先从 iCloud 中提取更改,通过委托方法询问用户是否一切都符合预期,然后合并到持久存储中,并在合并后将增量发送到 iCloud。
难道我做错了什么?或者这是一个集成错误?