2012-10-31 10 views
7

Używam narzędzia RestKit do parsowania JSON i odwzorowania go na Core Data NSManagedObjects. Oto przykładowy JSON.RestKit Dynamically Map Nazwa relacji na podstawie wartości

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

Stosując RKObjectMappingProvider i RKManagedObjectMapping ja odwzorowanie macierzy na oddzielne dane podstawowe Event obiektów "events". To działa dobrze.

Teraz Event ma dwie relacje na tym User i Photo. Teraz muszę odwzorować tablicę tematów na właściwy obiekt Core Data na podstawie wartości "subject_type" i ustawić ją na poprawną relację na Event.

Próbowałem używać RKDynamicObjectMapping, ale nie wiem, jak to określić dla "relacji dynamicznej". Potrzebuję jakiś sposób, aby ustawić nazwę relacji docelowej na podstawie wartości subject_type.

Jakieś myśli?

+0

Życzę ktoś odpowiedział na pytanie o rzeczywiste. – magma

Odpowiedz

1

W RestKit, RKDynamicMapping umożliwia również korzystanie z określonego bloku zrobić bardziej skomplikowane operacje dynamicznego mapowania jak ten, który opisujesz . Specyficzna metoda, która daje taką możliwość nazywa setObjectMappingForRepresentationBlock

Oto kilka docs o tej metodzie: http://restkit.org/api/latest/Classes/RKDynamicMapping.html#//api/name/setObjectMappingForRepresentationBlock:

testy jednostkowe

RestKit ilustrują kilka prostych spraw dla tej metody.

0

Wygląda na to, że powinieneś być w stanie wykorzystać RKDynamicObjectMapping (patrz Object Mapping). Można utworzyć odwzorowanie użytkownika oraz mapowanie zdjęcie, a następnie użyj RKDynamicObjectMapping tak:

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

Teraz, jak ustawić to w jednostce 'Event', aby używał właściwej relacji? – brynbodayle

0

Niedawno wpadłem na ten problem. Śledzenie przez RestKit, wygląda na to, że próbuje zastosować wszystkie mapowania obiektów do wszystkich relacji w instancji RKDynamicMapping. Zobacz applyRelationshipMappings w RKMappingOperation.m

Wymyśliłem rozwiązanie, które jest hackerem, ale nie wymagało większego modyfikowania kodu restkit.

W RKMappingOperation.m został zmodyfikowany w następujący sposób:

destinationObjectForMappingRepresentation:parentRepresentation:withMapping:inRelationship: 

dodawaniu następujące kod (wychodząc z komentarzem), który sprawdza, czy docelowy związek jest tego samego typu przedmiotu, jak to jest zastosowane i działa tylko wtedy, gdy pasuje. (To nie został poddany rygorystycznym testom, ale pracuje w moim konkretnym przypadku zastosowania.)

- (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; 
      } 
     } 

...

Powiązane problemy