我的服务器上有一个项目列表,我的应用程序在CoreData中有副本。
我的一个Web API下载了最新列表。
我已经成功编写了更新列的代码,并将新的行/项添加到我的本地CoreData存储中。这是处理从服务器接收的项目的代码(“name”唯一标识一行,假设Object
是实体):
NSFetchRequest* request = [[NSFetchRequest alloc] init];
[request setPredicate:[NSPredicate predicateWithFormat:@"name == %@", dictionary[@"name"]]];
[request setEntity:[NSEntityDescription entityForName:@"Object"
inManagedObjectContext:managedObjectContext]];
error = nil;
ObjectData* object = [[managedObjectContext executeFetchRequest:request error:&error] lastObject];
//### Handle error.
if (object == nil)
{
object = (ObjectData*)[NSEntityDescription insertNewObjectForEntityForName:@"Object"
inManagedObjectContext:managedObjectContext];
}
object.name = dictionary[@"name"];
object.place = dictionary[@"place"];
...
error = nil;
[managedObjectContext save:&error];
//### Handle error.
以上代码确实将服务器中的现有项和新项同步到CoreData。但是,服务器上删除的行不会从CoreData中删除。
同步删除的有效方法是什么?注意:Objects
有关系,因此只需删除整批并再次添加它们就行不通了。
例如,如何形成一个查询,删除所有名称不在最新下载列表中的行?
答案 0 :(得分:2)
如果服务器数据始终代表完整的表,请不要担心同步逻辑,只需替换客户端数据。
如果确实是同步情况,请考虑使用“软删除”。将“deletedAt”日期列添加到服务器和客户端表并同步。在拥有它们时限定客户端查询,但添加deletedAt!= nil。每隔一段时间(在客户端和服务器上)都会删除deletedAt比旧日期旧的行。
这样做的另一个好处是能够在您设置的旧日期阈值之前的某个时间撤消删除。
或者,要查找数据中不在加载对象中的对象:
NSArray *names = // the array of names in the newly loaded data
NSPredicate *deletedPredicate = [NSPredicate predicateWithFormat:@"NOT (name IN %@)",names];