2015-03-30 199 views
0

我正在關注如何直接使用RKMapperOperation映射傳入的JSON數據的一些建議帖子。我的實體對象正在數據存儲中創建,但沒有正確的關係。有趣的是,如果我在已經映射傳入的JSON(通過websockets)之後直接使用Core Data方法創建一個對象,那麼該操作似乎會在不正確的實體中「充實」我的關係。通過WebSocket連接 手動映射JSON對象時RestKit關係不映射

  • 我用下面的代碼映射它

    1. JSON數據進入應用程序,但關係不映射
    2. 我保存的其他紀錄:

      綜上所述順序在使用Core Data的本地創建的(不是RestKit)對象的同一個實體中。

    3. 從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_idsession_id值應建立與AttendeeSession實體的關係,但是當我看sqlite的數據基本核心數據的關係列,即使進入attendeeIdsessionId領域取得空白映射。一旦我在本地保存其他對象,那麼這些關係列就會被映射。

    有什麼想法?

    編輯︰ 我應該補充說,當一個完整的RestKit調用像.getObject或作爲.postObject的結果映射簽入,然後映射工作沒有問題。只有在這裏我手工繪製,它似乎分崩離析。

  • +0

    顯示JSON。是否有你使用操作而不是對象管理器的原因?該問題也沒有顯示你顯示的兩段代碼之間的聯繫... – Wain 2015-03-30 20:16:53

    +0

    我已經擴展了與JSON數據的問題以及如何使用函數調用。 – davidethell 2015-03-31 02:48:27

    +0

    所以看來你的問題確實是你想要創建存根對象,如果對象不存在,對於ID,所以你可以連接關係,然後填寫細節? – Wain 2015-03-31 07:04:44

    回答

    0

    這是最後的解決方案,它涉及到@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 
    } 
    

    現在,我們正在與內存緩存留下它並沒有看到重複的問題,其他國家報告。