J'ai des difficultés à configurer un mappage dynamique pour un tableau de résultats. Les objets de résultat que je souhaite mapper sont incorporés dans un «conteneur» qui décrit le type de l'objet inclus.Mappage dynamique RestKit avec des éléments imbriqués
J'ai JSON similaire à ce qui suit:
"list": {
"name": ""
"item_infos": [
{
"type": "TaskItem",
"item": {
"id": 0
"title": "A Task Item",
"task": "..."
}
"url": "..."
},
{
"type": "ReminderItem",
"item": {
"id": 0
"title": "A Reminder Item",
"reminder": "..."
}
"url": "..."
}]
}
J'aimerais mapper cela comme un objet List
avec un tableau de Item
s, où chaque élément peut être d'un type différent. Les différents type
sont finis et connus.
class List: NSManagedObject {
@NSManaged var name: String
@NSManaged var items: NSOrderedSet
}
class Item: NSManagedObject {
@NSManaged var identifier: Int32
@NSManaged var title: String
// Each mappable `Item` is responsible for providing its own
// mapping object. It's overridden in the subclasses below.
class func responseMappingForManagedObjectStore(dos: RKManagedObjectStore) -> RKEntityMapping { ... }
}
class TaskItem: Item {
@NSManaged var task: String
}
class ReminderItem: Item {
@NSManaged var reminder: String
}
Comment puis-je mapper le item
directement sous encastré la liste à l'aide RKDynamicMapping
tout en faisant usage du champ type
? J'essaie quelque chose le long de ces lignes pour la cartographie de réponse: une exception est levée
let listMapping = RKEntityMapping(forEntityForName: "List", inManagedObjectStore: store)
responseMapping.addAttributeMappingsFromDictionary(["name": "title"])
let dynamicItemMapping = RKDynamicMapping()
dynamicItemMapping.setObjectMappingForRepresentationBlock { representation in
let itemMapping: RKEntityMapping
switch representation.valueForKeyPath("type") as? String {
case .Some("TaskItem"): itemMapping = TaskItem.responseMappingForManagedObjectStore(objectStore)
case .Some("ReminderItem"): itemMapping = ReminderItem.responseMappingForManagedObjectStore(objectStore)
default: return nil
// This is the bit I'm failing to solve. How can I return a mapping
// that essentially "skips" a level of the JSON, and just maps the
// embedded `item`, not the `item_info`.
let itemInfoMapping = RKObjectMapping(forClass: NSMutableDictionary.self)
itemInfoMapping.addRelationshipMappingWithSourceKeyPath("item", mapping: itemMapping)
return itemInfoMapping
}
listMapping.addPropertyMapping(RKRelationshipMapping(
fromKeyPath: "item_infos",
toKeyPath: "items",
withMapping: dynamicItemMapping))
Avec cette application,:
-[__NSDictionaryM _isKindOfEntity:]: unrecognized selector sent to instance 0x7fd2603cb400
Ce qui ne me surprend pas, comme la façon dont la cartographie dynamique est mis en place ne me semble pas juste de toute façon - je suis à la recherche d'un moyen de "sauter" un niveau du JSON et seulement mapper le item
intégré.
Une autre tentative a été de préciser pleinement le fromKeyPath
comme "item_infos.item"
pour la relation avec le listMapping
, mais je ne peux pas utiliser le champ type
dans le bloc de mappage dynamique pour déterminer le type de Item
mapping à utiliser:
// ...
dynamicItemMapping.setObjectMappingForRepresentationBlock { representation in
// `type` inaccessible from the nested item representation
switch representation.valueForKeyPath("type") as? String {
case .Some("TaskItem"): return TaskItem.responseMappingForManagedObjectStore(objectStore)
case .Some("ReminderItem"): return ReminderItem.responseMappingForManagedObjectStore(objectStore)
default: return nil
}
listMapping.addPropertyMapping(RKRelationshipMapping(
fromKeyPath: "item_infos.item",
toKeyPath: "items",
withMapping: dynamicItemMapping))
Vous n'avez pas dit quel est le problème. Personnellement, je n'aurais pas plusieurs entités différentes, j'en aurais 1 avec un identifiant de type. – Wain
@Wain Désolé, je n'ai pas fait le problème très clair. J'ai mis à jour la question, mais en un mot, les exemples de mappage que j'ai donnés ne fonctionnent pas - le premier déclenche une exception et le second essaie d'effectuer le mappage dynamique basé sur un chemin clé inaccessible depuis le dictionnaire dans le bloc de mappage dynamique (en raison du 'fromKeyPath' du mappage de relation étant un niveau trop profond). Les entités sont simplifiées par souci de clarté/concision dans la question; en réalité, les objets sont suffisamment différents pour justifier d'être des entités distinctes. – Stuart