手动映射JSON对象时RestKit关系不映射
问题描述:
我正在关注如何直接使用RKMapperOperation映射传入的JSON数据的一些建议帖子。我的实体对象正在数据存储中创建,但没有正确的关系。有趣的是,如果我在已经映射传入的JSON(通过websockets)之后直接使用Core Data方法创建一个对象,那么该操作似乎会在不正确的实体中“充实”我的关系。通过WebSocket连接 手动映射JSON对象时RestKit关系不映射
- JSON数据进入应用程序,但关系不映射
- 我保存的其他纪录:
综上所述顺序在使用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订阅为no时调用函数tified:
let jsonString = "<the JSON data per above>"
let mappingResult = self.mapEntityFromJson(jsonString, key: "checkin", mapping: self.checkinMapping())
的attendee_id
和session_id
值应建立与Attendee
和Session
实体的关系,但是当我看sqlite的数据基本核心数据的关系列,即使进入attendeeId
和sessionId
领域取得空白映射。一旦我在本地保存其他对象,那么这些关系列就会被映射。
有什么想法?
编辑︰ 我应该补充说,当一个完整的RestKit调用像.getObject或作为.postObject的结果映射签入,然后映射工作没有问题。只有在这里我手工绘制,它似乎分崩离析。
答
这是最后的解决方案,它涉及到@wain的大量帮助以及另一篇文章中关于需要使operationQueue等待所有操作完成或否则映射过程尚未完成映射关系的关键点。所以我的NSManagedObject返回时没有连接关系。将私有子上下文用于适当的并发和保存数据以及等待问题解决了问题。下面是最终映射代码:
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 mapperContext = self.objectStore.newChildManagedObjectContextWithConcurrencyType(NSManagedObjectContextConcurrencyType.PrivateQueueConcurrencyType, tracksChanges: true)
let mappingsDictionary = [ key: mapping ]
let mappingDS = RKManagedObjectMappingOperationDataSource(managedObjectContext: mapperContext, cache: self.objectStore.managedObjectCache)
var mappingResult: RKMappingResult? = nil
var result: NSManagedObject? = nil
let mapper = RKMapperOperation(representation: parsedData, mappingsDictionary: mappingsDictionary)
mappingDS.operationQueue = self.operationQueue
mappingDS.parentOperation = mapper
mapper.mappingOperationDataSource = mappingDS
var mappingError: NSError? = nil
let isMapped = mapper.execute(&mappingError)
// Necessary to wait for relationships to map.
if self.operationQueue!.operationCount > 0 {
self.operationQueue!.waitUntilAllOperationsAreFinished()
}
if (isMapped && mappingError == nil) {
mapperContext.saveToPersistentStore(&error)
mappingResult = mapper.mappingResult
}
if mappingResult != nil {
result = mappingResult!.firstObject() as? NSManagedObject
}
return result
}
现在,我们正在与内存缓存留下它并没有看到重复的问题,其他国家报告。
显示JSON。是否有你使用操作而不是对象管理器的原因?该问题也没有显示你显示的两段代码之间的联系... – Wain 2015-03-30 20:16:53
我已经扩展了与JSON数据的问题以及如何使用函数调用。 – davidethell 2015-03-31 02:48:27
所以看来你的问题确实是你想要创建存根对象,如果对象不存在,对于ID,所以你可以连接关系,然后填写细节? – Wain 2015-03-31 07:04:44