在 Restkit 更新期间保持与本地用户对象的关系
Persisting relationship with local user object during a Restkit update
我正在开发一个使用 Restkit 将 "Events" 与 JSON API 同步的事件应用程序。映射大致如下所示。
var eventsMapping = RKEntityMapping(forEntityForName: "Event", inManagedObjectStore: managedObjectStore)
eventsMapping.identificationAttributes = ["eventID", "name", "eventDescription"]
eventsMapping.addAttributeMappingsFromDictionary([
"id":"eventID",
"title":"name",
"description":"eventDescription",
(more mapping attributes here, etc...)
])
使用 NSFetchedResultsController 显示事件。在本地,创建了一个 'User' NSManagedObject...但是这个对象只是应用程序的本地对象,不会通过 Restkit 同步到服务器。 "User" 与事件具有一对多关系,目的是用户可以 "save" 他们正在参加的事件。 (注:此时Core Data关系删除规则的两边设置为"no action.")保存大致是这样的
var managedObjectContext = RKManagedObjectStore.defaultStore().mainQueueManagedObjectContext
currentUser.mutableSetValueForKey("events").addObject(event)
managedObjectContext?.saveToPersistentStore(&error)
到目前为止,一切正常,选定的事件已成功存储并与用户一起保存,并按预期通过应用程序重新启动持续存在。但是,有一种情况会导致从用户那里删除事件,即在服务器上对该特定事件进行更新时。当 Restkit 检测到这一点并更新事件时,根据我在 NSFetchedResultsController didChangeObject 中放置的断点,显然 Restkit and/or Core Data 实际上正在删除事件,然后将其与更新一起插入回来。这是透明的,在大多数情况下都很好,但在这种情况下,我认为初始删除是中断用户事件的原因。
当然,上面的 eventsMapping 没有以任何方式引用与用户的任何关系,因此这可能是关系中断的另一个原因。我一直在阅读有关 Restkit 关系的更多信息,并且在成功关联对象之前,我在 Restkit 中使用了关系/属性 映射,但在那种情况下,两个对象都存在于 API 上。在这种情况下,这里的 User 根本不是 API 的一部分,正如我所解释的那样,它只是本地的。那么我还应该使用 Restkit 关系映射吗?或者我应该尝试通过另一种方式完成上述所有操作?
我找到了答案,我在上面的代码中犯了一个错误。在映射的标识属性上,我有三个不同的属性,而我只应该使用主键永远不会改变的属性 (eventID)。
eventsMapping.identificationAttributes = ["eventID"]
显然发生的事情是因为我将 title/name 指定为标识属性,只要服务器上的标题发生更改,Restkit 就会将其标识为 new/different object 并删除"old" object 并插入 "new" 一个。当我只更改它以指定主键时,它触发了更新,我与用户的关系仍然存在。
给一开始让我震惊的其他人的另一个注意事项:我遇到的一些旧信息帮助我解决了这个问题,据说在映射上使用 primaryKeyAttribute。这显然是过时的信息:请改用 identificationAttributes。
我正在开发一个使用 Restkit 将 "Events" 与 JSON API 同步的事件应用程序。映射大致如下所示。
var eventsMapping = RKEntityMapping(forEntityForName: "Event", inManagedObjectStore: managedObjectStore)
eventsMapping.identificationAttributes = ["eventID", "name", "eventDescription"]
eventsMapping.addAttributeMappingsFromDictionary([
"id":"eventID",
"title":"name",
"description":"eventDescription",
(more mapping attributes here, etc...)
])
使用 NSFetchedResultsController 显示事件。在本地,创建了一个 'User' NSManagedObject...但是这个对象只是应用程序的本地对象,不会通过 Restkit 同步到服务器。 "User" 与事件具有一对多关系,目的是用户可以 "save" 他们正在参加的事件。 (注:此时Core Data关系删除规则的两边设置为"no action.")保存大致是这样的
var managedObjectContext = RKManagedObjectStore.defaultStore().mainQueueManagedObjectContext
currentUser.mutableSetValueForKey("events").addObject(event)
managedObjectContext?.saveToPersistentStore(&error)
到目前为止,一切正常,选定的事件已成功存储并与用户一起保存,并按预期通过应用程序重新启动持续存在。但是,有一种情况会导致从用户那里删除事件,即在服务器上对该特定事件进行更新时。当 Restkit 检测到这一点并更新事件时,根据我在 NSFetchedResultsController didChangeObject 中放置的断点,显然 Restkit and/or Core Data 实际上正在删除事件,然后将其与更新一起插入回来。这是透明的,在大多数情况下都很好,但在这种情况下,我认为初始删除是中断用户事件的原因。
当然,上面的 eventsMapping 没有以任何方式引用与用户的任何关系,因此这可能是关系中断的另一个原因。我一直在阅读有关 Restkit 关系的更多信息,并且在成功关联对象之前,我在 Restkit 中使用了关系/属性 映射,但在那种情况下,两个对象都存在于 API 上。在这种情况下,这里的 User 根本不是 API 的一部分,正如我所解释的那样,它只是本地的。那么我还应该使用 Restkit 关系映射吗?或者我应该尝试通过另一种方式完成上述所有操作?
我找到了答案,我在上面的代码中犯了一个错误。在映射的标识属性上,我有三个不同的属性,而我只应该使用主键永远不会改变的属性 (eventID)。
eventsMapping.identificationAttributes = ["eventID"]
显然发生的事情是因为我将 title/name 指定为标识属性,只要服务器上的标题发生更改,Restkit 就会将其标识为 new/different object 并删除"old" object 并插入 "new" 一个。当我只更改它以指定主键时,它触发了更新,我与用户的关系仍然存在。
给一开始让我震惊的其他人的另一个注意事项:我遇到的一些旧信息帮助我解决了这个问题,据说在映射上使用 primaryKeyAttribute。这显然是过时的信息:请改用 identificationAttributes。