2012-10-31 9 views
7

Ich verwende RestKit, um JSON zu analysieren und es in Core Data NSManagedObjects zu mappen. Hier ist ein Beispiel JSON.RestKit Dynamically Map Beziehungsname basierend auf Wert

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

Mit RKObjectMappingProvider und RKManagedObjectMapping Ich Abbilden der "events" Array in separate Core Data Event Objekte. Das funktioniert gut.

Jetzt hat Event zwei Beziehungen auf es User und Photo. Nun muss ich das Subjekt-Array dem richtigen Core Data-Objekt basierend auf dem Wert "subject_type" zuordnen und dieses auf die korrekte Beziehung auf Event setzen.

Ich versuchte mit RKDynamicObjectMapping, aber ich weiß nicht, wie man das für eine "dynamische Beziehung" angibt. Ich brauche eine Möglichkeit, den Namen der Zielbeziehung basierend auf dem Wert subject_type festzulegen.

Irgendwelche Gedanken?

+0

Ich wünschte, jemand hier die eigentliche Frage beantwortet. – magma

Antwort

1

In RestKit, RKDynamicMapping ermöglicht auch die Verwendung eines bestimmten Blöcke komplexere dynamischen Mapping-Operationen wie das zu tun, was Sie beschreiben, . Das spezielle Verfahren, die diese Fähigkeit gibt, ist setObjectMappingForRepresentationBlock genannt

Hier sind einige Dokumente auf dieser Methode: http://restkit.org/api/latest/Classes/RKDynamicMapping.html#//api/name/setObjectMappingForRepresentationBlock:

Die RestKit Unit-Tests zeigen einige einfache Fälle für diese Methode.

0

Es scheint, dass Sie RKDynamicObjectMapping verwenden können (siehe Object Mapping). Sie könnten eine Benutzerzuordnung und ein Foto-Mapping erstellen und dann RKDynamicObjectMapping wie folgt verwenden:

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

Nun, wie setze ich dies auf die "Event" -Entität, so dass es die richtige Beziehung verwendet? – brynbodayle

0

Ich bin kürzlich auf dieses Problem gestoßen. Bei der Verfolgung durch RestKit scheint es, als ob versucht wird, alle Objektzuordnungen auf alle Beziehungen in einer RKDynamicMapping-Instanz anzuwenden. Siehe applyRelationshipMappings in RKMappingOperation.m

Ich kam mit einer Lösung, die ein Hack ist, aber ich brauchte Restkit-Code nicht stark zu ändern.

In RKMappingOperation.m, I modifiziert, um die folgende Methode:

destinationObjectForMappingRepresentation:parentRepresentation:withMapping:inRelationship: 

I den folgenden Code hinzugefügt (beginnend mit dem Kommentar), das das Ziel der Beziehung überprüft, ob die gleiche Art von Objekt ist als angewendet, und fährt nur fort, wenn es übereinstimmt. (Dies ist nicht strengen Tests unterzogen, wird aber in meinem speziellen Anwendungsfall zu arbeiten.)

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

...