RestKit - 从索引端点映射资源集合
RestKit - Mapping a collection of resources from an index endpoint
我在当前项目中使用 RestKit 来促进与定制 REST 的通信 API。我在从索引端点检索资源集合时遇到问题。我能够检索资源,但是我无法将它们映射到目标 class。
这是详细信息(我用小部件替换了相关的实际业务对象)。
端点是 GET /api/v1/widgets。从端点返回的 JSON 如下所示:
{"widgets": [
{
"widgets": {
"name": "whatsit",
"material": "wood",
"crafted_by": "Hrunkner"
}
},
{
"widgets": {
"name": "doodad",
"material": "carbon fiber",
"crafted_by": "Zaphod"
}
}
]}
我知道上面的 JSON 结构对于每个资源的根节点名称是特殊的,但是目前我无法控制。
我在 WidgetManager class 中使用以下代码来执行请求:
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
// apiBaseURL equals @"http://localhost:3000/api/v1/"
NSURL *apiBaseURL = [NSURL URLWithString:appDelegate.apiBaseURL];
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:apiBaseURL];
NSString *itemsPath = @"widgets";
NSString *keyPath = @"widgets.widgets";
NSIndexSet *statusCodeSet = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
RKObjectMapping *requestMapping = [[Widget widgetMapping] inverseMapping];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping: requestMapping
objectClass:[Widget class]
rootKeyPath:keyPath
method:RKRequestMethodGET];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:requestMapping
method:RKRequestMethodGET
pathPattern:nil
keyPath:keyPath
statusCodes:statusCodeSet];
[manager addRequestDescriptor: requestDescriptor];
[manager addResponseDescriptor:responseDescriptor];
[manager getObjectsAtPath:@"widgets"
parameters:@{}
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
[appDelegate setWidgets:[mappingResult array]];
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"FAIL");
}];
我的 [Widget 映射] 方法如下所示:
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[Widget class]];
[mapping addAttributeMappingsFromDictionary:@{
@"name": @"name",
@"material": @"material",
@"crafted_by": @"craftedBy"
}];
return mapping;
在我看来,使用 inverseMapping 是个问题,但是当我尝试使用 [Widget widgetMapping] 而不是 [[Widget widgetMapping] inverseMapping] 作为请求映射时,我收到以下错误
RKRequestDescriptor objects must be initialized with a mapping whose
target class is NSMutableDictionary, got Widget (see
[RKObjectMapping requestMapping])
我在这里做错了什么?我应该如何正确配置我的请求以将每个返回的对象映射到 Widget class?
感谢并为我的问题中的任何遗漏或错误道歉。
事实证明,仅对响应描述符使用逆映射允许对象映射成功进行。以前我试图对请求和响应描述符使用相同的映射,但这是行不通的。因此,将对 requestMapping 的分配更改为简单的 [Widget requestmapping]
,然后将 [requestMapping inverseMapping]
传递给请求描述符 init 解决了我的问题。当然,这将需要重命名局部变量 requestMapping
,因为它实际上对请求描述符没有用。
以下问题的答案在澄清请求与响应描述符中的映射功能方面提供了正确方向的推动:
我在当前项目中使用 RestKit 来促进与定制 REST 的通信 API。我在从索引端点检索资源集合时遇到问题。我能够检索资源,但是我无法将它们映射到目标 class。
这是详细信息(我用小部件替换了相关的实际业务对象)。
端点是 GET /api/v1/widgets。从端点返回的 JSON 如下所示:
{"widgets": [
{
"widgets": {
"name": "whatsit",
"material": "wood",
"crafted_by": "Hrunkner"
}
},
{
"widgets": {
"name": "doodad",
"material": "carbon fiber",
"crafted_by": "Zaphod"
}
}
]}
我知道上面的 JSON 结构对于每个资源的根节点名称是特殊的,但是目前我无法控制。
我在 WidgetManager class 中使用以下代码来执行请求:
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
// apiBaseURL equals @"http://localhost:3000/api/v1/"
NSURL *apiBaseURL = [NSURL URLWithString:appDelegate.apiBaseURL];
RKObjectManager *manager = [RKObjectManager managerWithBaseURL:apiBaseURL];
NSString *itemsPath = @"widgets";
NSString *keyPath = @"widgets.widgets";
NSIndexSet *statusCodeSet = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
RKObjectMapping *requestMapping = [[Widget widgetMapping] inverseMapping];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping: requestMapping
objectClass:[Widget class]
rootKeyPath:keyPath
method:RKRequestMethodGET];
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:requestMapping
method:RKRequestMethodGET
pathPattern:nil
keyPath:keyPath
statusCodes:statusCodeSet];
[manager addRequestDescriptor: requestDescriptor];
[manager addResponseDescriptor:responseDescriptor];
[manager getObjectsAtPath:@"widgets"
parameters:@{}
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
[appDelegate setWidgets:[mappingResult array]];
} failure:^(RKObjectRequestOperation *operation, NSError *error) {
NSLog(@"FAIL");
}];
我的 [Widget 映射] 方法如下所示:
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[Widget class]];
[mapping addAttributeMappingsFromDictionary:@{
@"name": @"name",
@"material": @"material",
@"crafted_by": @"craftedBy"
}];
return mapping;
在我看来,使用 inverseMapping 是个问题,但是当我尝试使用 [Widget widgetMapping] 而不是 [[Widget widgetMapping] inverseMapping] 作为请求映射时,我收到以下错误
RKRequestDescriptor objects must be initialized with a mapping whose target class is NSMutableDictionary, got Widget (see [RKObjectMapping requestMapping])
我在这里做错了什么?我应该如何正确配置我的请求以将每个返回的对象映射到 Widget class?
感谢并为我的问题中的任何遗漏或错误道歉。
事实证明,仅对响应描述符使用逆映射允许对象映射成功进行。以前我试图对请求和响应描述符使用相同的映射,但这是行不通的。因此,将对 requestMapping 的分配更改为简单的 [Widget requestmapping]
,然后将 [requestMapping inverseMapping]
传递给请求描述符 init 解决了我的问题。当然,这将需要重命名局部变量 requestMapping
,因为它实际上对请求描述符没有用。
以下问题的答案在澄清请求与响应描述符中的映射功能方面提供了正确方向的推动: