1

我的服务器上有一个项目列表,我的应用在 CoreData 中有一个副本。

我的一个 Web API 下载了最新列表。

我已经成功编写了更新列的代码,并将新的行/项目添加到我的本地 CoreData 存储中。这是处理从服务器接收到的项目的代码(“名称”唯一标识一行,假设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有关系,所以简单地删除整个批次并再次添加它们是行不通的。

例如,如何形成一个查询来删除所有名称不在下载的最新列表中的行?

4

1 回答 1

2

如果服务器数据总是代表完整的表,不要担心同步逻辑,只需替换客户端数据。

如果确实是同步情况,请考虑使用“软删除”。将“deletedAt”日期列添加到您的服务器和客户端表并同步它。根据您的要求对客户端查询进行限定,但添加 deletedAt != nil。每隔一段时间(在客户端和服务器上)删除已删除日期早于某个旧日期的行。

这样做的另一个好处是能够在您设置的旧日期阈值之前的某个时间撤消删除。

或者,要在数据中查找不在加载对象中的对象:

NSArray *names = // the array of names in the newly loaded data
NSPredicate *deletedPredicate = [NSPredicate predicateWithFormat:@"NOT (name IN %@)",names];
于 2013-09-02T19:19:32.970 回答