【发布时间】:2015-03-30 19:28:36
【问题描述】:
我正在关注一些关于如何使用 RKMapperOperation 直接映射传入 JSON 数据的建议帖子。我的实体对象正在数据存储中创建,但没有正确的关系。有趣的是,如果我在已经映射传入的 JSON(通过 websockets)之后直接使用 Core Data 方法创建一个对象,那么该操作似乎会“充实”我在不正确实体中的关系。
总结顺序:
- JSON 数据通过 websocket 连接进入应用程序
- 我使用下面的代码映射它,但没有映射关系
- 我使用带有 Core Data 的本地创建(不是 RestKit)对象将其他一些记录保存在同一实体中。
- 我的从 JSON 映射的对象现在附加了它的关系!
这是 JSON 数据:
{
"checkin": {
"session_id": 1,
"attendee_id": 70,
"source": "list",
"created_at": "2015-03-26 11:53:08",
"cache_id": "9234d700852df5c7402b87adf6ecfc19",
"checkout": "0",
"updated_at": "2015-03-27 03:53:09",
"id": 359
}
}
这是我的映射函数
func mapEntityFromJson(JSONString: String, key: String, mapping: RKEntityMapping!) -> NSManagedObject? {
let MIMEType = "application/json"
var error: NSError? = nil
let data = JSONString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
let jsonDictionary: NSDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: &error) as NSDictionary
let parsedData: AnyObject! = RKMIMETypeSerialization.objectFromData(data, MIMEType: MIMEType, error: &error)
if (parsedData == nil && error != nil) {
// Parser error...
return nil
}
let mappingsDictionary = [ key: mapping ]
let mappingDS = RKManagedObjectMappingOperationDataSource(managedObjectContext: self.objectStore.persistentStoreManagedObjectContext, cache: self.objectStore.managedObjectCache)
let mapper = RKMapperOperation(representation: parsedData, mappingsDictionary: mappingsDictionary)
mapper.mappingOperationDataSource = mappingDS
var mappingError: NSError? = nil
let isMapped = mapper.execute(&mappingError)
if (isMapped && mappingError == nil) {
// Trying to save twice per some other example
self.objectStore.persistentStoreManagedObjectContext.save(&error)
self.objectStore.persistentStoreManagedObjectContext.saveToPersistentStore(&error)
let result = mapper.mappingResult.firstObject() as NSManagedObject
return result
}
return nil
}
这是我传递给这个函数的关系映射:
func checkinMapping() -> RKEntityMapping {
let checkinMapping = RKEntityMapping(forEntityForName: "Checkin", inManagedObjectStore: objectStore)
let checkinDictionary = ["source": "source", "checkout": "checkout", "cache_id": "cacheId", "attendee_id": "attendeeId", "session_id": "sessionId"]
checkinMapping.addAttributeMappingsFromDictionary(baseRecordDictionary)
checkinMapping.addAttributeMappingsFromDictionary(checkinDictionary)
checkinMapping.addConnectionForRelationship("attendee", connectedBy: ["attendeeId": "id"])
checkinMapping.addConnectionForRelationship("session", connectedBy: ["sessionId": "id"])
checkinMapping.identificationAttributes = ["cacheId"]
checkinMapping.setDefaultValueForMissingAttributes = true
return checkinMapping
}
以下是通知 websocket 订阅时函数的调用方式:
let jsonString = "<the JSON data per above>"
let mappingResult = self.mapEntityFromJson(jsonString, key: "checkin", mapping: self.checkinMapping())
attendee_id 和session_id 值应该与Attendee 和Session 实体建立关系,但是当我查看Core Data 底层的sqlite 数据时,即使传入attendeeId,关系列也是空白的和 sessionId 字段被映射。一旦我在本地进行另一个保存,那么这些关系列就会被映射。
有什么想法吗?
编辑: 我应该补充一点,当从完整的 RestKit 调用(如 .getObject 或作为 .postObject 的结果)映射签入时,映射将毫无问题地工作。只是在我这里的手动映射中,它似乎分崩离析。
【问题讨论】:
-
显示 JSON。您使用操作而不是对象管理器是否有原因?该问题也没有显示您显示的两段代码之间的链接......
-
我已经用 JSON 数据以及如何使用函数调用扩展了这个问题。
-
所以看起来你的问题真的是你想要创建存根对象,如果对象不存在,那么你可以连接关系,然后稍后填写详细信息?
-
其实attendee_id和session_id分别引用的attendee对象和session对象在签到之前就一直存在。在对象通过 Web 套接字进入之前,这些记录始终存在。无论如何,我将探索以 JSON 格式发送它们,但考虑到我已经在本地拥有记录,这将使通过的数据大小增加一倍以上,这似乎效率低下。
-
如果您已经拥有它们,则无需将它们嵌套发送。您确定在运行此部分之前它们已保存到磁盘吗?