2012-10-31 36 views
7

我正在使用RestKit來解析JSON並將其映射到核心數據NSManagedObjects中。這裏是一個示例JSON。RestKit根據值動態映射關係名稱

{ 
    "events": [ 
     { 
      "description": "...", 
      "subject_type": "photo", 
      "subject": { 
       "id": 1, 
       "thumb_url": "...", 
       "medium_url": "...", 
       "large_url": "..." 
      } 
     }, 
     { 
      "description": "...", 
      "subject_type": "user", 
      "subject": { 
       "id": 1, 
       "username": "...", 
       "followers": "..." 
      } 
     } 
    ] 
} 

使用RKObjectMappingProviderRKManagedObjectMapping我映射"events"陣列成獨立的核心數據Event對象。這工作正常。

現在Event上有兩個關係UserPhoto。現在我需要根據"subject_type"的值將主體數組映射到適當的核心數據對象,並將其設置爲Event上的正確關係。

我試過使用RKDynamicObjectMapping,但我不知道如何指定「動態關係」。我需要一些方法來根據subject_type的值設置目標關係的名稱。

有什麼想法?

+0

我希望有人在這裏得到解答實際問題。 – magma

回答

0

看來你應該能夠使用RKDynamicObjectMapping(見Object Mapping)。您可以創建一個用戶映射和照片映射,然後用你的RKDynamicObjectMapping這樣的:

[dynamicMapping setObjectMapping:userMapping 
       whenValueOfKeyPath:@"subject_type" 
         isEqualTo:@"user"]; 
[dynamicMapping setObjectMapping:photoMapping 
       whenValueOfKeyPath:@"subject_type" 
         isEqualTo:@"photo"]; 
+0

現在我該如何在'Event'實體上設置它,以便它使用正確的關係? – brynbodayle

0

我最近遇到了這個問題。通過RestKit追蹤,它看起來像試圖將所有對象映射應用到RKDynamicMapping實例中的所有關係。請參閱applyRelationshipMappings在RKMappingOperation.m

我想出了一個解決方案,它是一個黑客攻擊,但並不需要我大量修改restkit代碼。

在RKMappingOperation.m,我修改了以下方法:

destinationObjectForMappingRepresentation:parentRepresentation:withMapping:inRelationship: 

添加以下代碼(從註釋)來檢查的關係的目的地是否是相同類型的對象作爲正被應用,並且只有在匹配時纔會繼續。 (這個沒有經過嚴格的測試,但工作在我的特定用例。)

- (id)destinationObjectForMappingRepresentation:(id)representation parentRepresentation:(id)parentRepresentation withMapping:(RKMapping *)mapping inRelationship:(RKRelationshipMapping *)relationshipMapping 
{ 
    RKObjectMapping *concreteMapping = nil; 
    if ([mapping isKindOfClass:[RKDynamicMapping class]]) { 
     concreteMapping = [(RKDynamicMapping *)mapping objectMappingForRepresentation:representation]; 
     if (! concreteMapping) { 
      RKLogDebug(@"Unable to determine concrete object mapping from dynamic mapping %@ with which to map object representation: %@", mapping, representation); 
      return nil; 
     } 
     // Make sure the destination of a core data relationship is the right entity class for the object we're mapping; 
     if ([self.destinationObject respondsToSelector:@selector(managedObjectContext)]) 
     { 
      NSEntityDescription *destinationEntity = [self.destinationObject entity]; 
      NSDictionary *destinationPropertiesDictionary = [destinationEntity propertiesByName]; 
      NSRelationshipDescription *destinationPropertyForDestinationKeyPath = [destinationPropertiesDictionary valueForKey:relationshipMapping.destinationKeyPath]; 
      NSString *relationshipDestinationClassName = [[destinationPropertyForDestinationKeyPath destinationEntity] name]; 
      NSString *mappedObjectClassName = [NSString stringWithCString:class_getName(concreteMapping.objectClass) encoding:NSUTF8StringEncoding]; 
      if (![relationshipDestinationClassName isEqualToString:mappedObjectClassName]) 
      { 
       return nil; 
      } 
     } 

...