带有嵌套项的 RestKit 动态映射
RestKit dynamic mapping with nested items
我在为一组结果配置动态映射时遇到问题。我想要映射的结果对象嵌入在描述封闭对象类型的 "container" 中。
我有 JSON 类似于以下内容:
"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": "..."
}]
}
我想将其映射为具有 Item
数组的 List
对象,其中每个项目可能属于不同类型。不同的 type
是有限且已知的。
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
}
如何使用 RKDynamicMapping
将嵌入的 item
直接映射到列表下,同时仍然使用 type
字段?我正在尝试沿着这些方向进行响应映射:
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))
使用此映射,引发异常:
-[__NSDictionaryM _isKindOfEntity:]: unrecognized selector sent to instance 0x7fd2603cb400
这并不让我感到惊讶,因为动态映射的设置方式无论如何都感觉不对 - 我正在寻找一种方法来 "skip" JSON 的水平] 并且只映射嵌入的 item
.
另一种尝试是将 fromKeyPath
完全指定为 "item_infos.item"
以表示与 listMapping
的关系,但我无法使用动态映射块中的 type
字段来确定要使用的 Item
映射类型:
// ...
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))
您无法完全按照您的意愿去做,因为您正在将核心数据关系连接到将成为包含托管对象的字典数组。
最简单的解决方案是通过在源密钥(路径)的开头添加 item.
将您的跳过逻辑从原处移除,并为托管对象(任务和提醒)创建所有映射).所以
"item.title" : "title"
我在为一组结果配置动态映射时遇到问题。我想要映射的结果对象嵌入在描述封闭对象类型的 "container" 中。
我有 JSON 类似于以下内容:
"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": "..."
}]
}
我想将其映射为具有 Item
数组的 List
对象,其中每个项目可能属于不同类型。不同的 type
是有限且已知的。
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
}
如何使用 RKDynamicMapping
将嵌入的 item
直接映射到列表下,同时仍然使用 type
字段?我正在尝试沿着这些方向进行响应映射:
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))
使用此映射,引发异常:
-[__NSDictionaryM _isKindOfEntity:]: unrecognized selector sent to instance 0x7fd2603cb400
这并不让我感到惊讶,因为动态映射的设置方式无论如何都感觉不对 - 我正在寻找一种方法来 "skip" JSON 的水平] 并且只映射嵌入的 item
.
另一种尝试是将 fromKeyPath
完全指定为 "item_infos.item"
以表示与 listMapping
的关系,但我无法使用动态映射块中的 type
字段来确定要使用的 Item
映射类型:
// ...
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))
您无法完全按照您的意愿去做,因为您正在将核心数据关系连接到将成为包含托管对象的字典数组。
最简单的解决方案是通过在源密钥(路径)的开头添加 item.
将您的跳过逻辑从原处移除,并为托管对象(任务和提醒)创建所有映射).所以
"item.title" : "title"