我的服务器上有一个项目列表,我的应用在 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 中删除。
同步删除的有效方法是什么?注意:对象
之间存在关系,因此简单地删除所有对象并再次添加它们是行不通的。
例如,我如何形成一个查询来删除名称不在已下载的最新列表中的所有行?
最佳答案
如果服务器数据始终代表完整的表,不用担心同步逻辑,只需替换客户端数据即可。
如果确实是同步情况,请考虑使用“软删除”。将“deletedAt”日期列添加到您的服务器和客户端表并同步它。对客户查询进行限定,但添加 deletedAt != nil。每隔一段时间(在客户端和服务器上)删除 deletedAt 早于某个旧日期的行。
这样做的另一个好处是能够在您设置的旧日期阈值之前的某个时间撤消删除。
或者,在您的数据中查找不在加载对象中的对象:
NSArray *names = // the array of names in the newly loaded data
NSPredicate *deletedPredicate = [NSPredicate predicateWithFormat:@"NOT (name IN %@)",names];
关于ios - 如何将 CoreData 表与在线资源同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18579362/