【问题标题】:How to map RKClient's RKResponse with an RKObjectMapping如何使用 R 对象映射映射客户端的响应
【发布时间】:2012-01-17 05:46:26
【问题描述】:

我正在使用 RestKit 的 RKClient 进行图像数据和一些值的多部分发布,如下所示:

RKParams* params = [RKParams params];
[params setValue:foo.accountId forParam:@"accountId"];
[params setValue:foo.identifier forParam:@"fooId"];
[params setValue:_photoId forParam:@"photoId"];
[params setData:data MIMEType:@"image/png" forParam:@"image"];
[[RKClient sharedClient] post:@"/foo/uploadPhoto" params:params delegate:self];

这很好用,我的后端服务器使用服务器端模型对象的 JSON 表示进行响应,它看起来像这样:

{"id":"4ee2b4670364720c089e75b9","accountId":"4ebee3469ae2d8adf983c561","fooId":"4ec0983d036463d900841f0b","photoId":"E5B20AF1-9F10-4175-8262-852BDA3DEDE9","filename":"4ebee3469ae2d8adf983c561_4ec0983d036463d900841f0b_E5B20AF1-9F10-4175-8262-852BDA3DEDE9","contentType":"image/png"}

我现在需要做的是将它映射到我的客户端 (iOS) 模型对象。客户端模型对象几乎相同,但不完全相同(因此不能选择使用 RKJSONParser 的 objectFromString 方法),因此我定义了一个自定义 RKObjectMapping 来处理映射。 RKClient 的委托只得到一个 RKResponse,那么如何使用响应和映射器来获取我的客户端模型对象的实例?

注意:需要明确的是,我非常熟悉使用 RKObjectManager 发布对象和映射响应时的工作原理。我的情况的独特部分是我正在使用 RKClient 来实现多部分发布。不幸的是,RKClient 似乎没有像 RKObjectManager 那样处理响应映射的简单方法......除非我遗漏了一些东西(我希望并且现在你们都会为我指出;)。

【问题讨论】:

    标签: objective-c cocoa-touch restkit


    【解决方案1】:

    好吧,this post was similar(但没有功能)它给了我一些关于在 RKObjectLoader 上使用此方法的新技术的想法

    - (RKObjectLoader *)postObject:(id<NSObject>)object delegate:(id<RKObjectLoaderDelegate>)delegate block:(void ( ^ ) ( RKObjectLoader *))block
    

    所以现在我可以从使用 RKClient 不明显的映射中获益。

    路由器设置:

    RKObjectManager *objectManager = [RKObjectManager objectManagerWithBaseURL:kApiUrlBase];
    [objectManager.router routeClass:[PAPetPhoto class] toResourcePath:@"/pet/uploadPhoto" forMethod:RKRequestMethodPOST];
    

    映射设置:

    RKObjectMapping *papetPhotoMapping = [RKObjectMapping mappingForClass:[PAPetPhoto class]];
    [papetPhotoMapping mapKeyPath:@"id" toAttribute:@"identifier"];
    [papetPhotoMapping mapAttributes:@"accountId", @"petId", @"photoId", @"filename", @"contentType", nil];
    [objectManager.mappingProvider addObjectMapping:papetPhotoMapping];
    [objectManager.mappingProvider setSerializationMapping:[papetPhotoMapping inverseMapping] forClass:[PAPetPhoto class]];
    [objectManager.mappingProvider setMapping:papetPhotoMapping forKeyPath:@"petPhoto"];
    

    帖子:(请注意,由于我在块中构建了所有参数,因此我的对象只是一个虚拟实例,用于触发正确的路由和映射器)。

        PAPetPhoto *photo = [[PAPetPhoto alloc] init];
        [[RKObjectManager sharedManager] postObject:photo delegate:self block:^(RKObjectLoader *loader){
    
            RKParams* params = [RKParams params];
            [params setValue:pet.accountId forParam:@"accountId"];
            [params setValue:pet.identifier forParam:@"petId"];
            [params setValue:_photoId forParam:@"photoId"];
            [params setValue:_isThumb ? @"THUMB" : @"FULL" forParam:@"photoSize"];
            [params setData:data MIMEType:@"image/png" forParam:@"image"];
    
            loader.params = params;
        }];
    

    服务器端点(Java、Spring MVC)

        @RequestMapping(value = "/uploadPhoto", method = RequestMethod.POST)
        @ResponseBody
        public Map<String, Object> handleFormUpload(@RequestParam("accountId") String accountId,
                                        @RequestParam("petId") String petId,
                                        @RequestParam("photoId") String photoId,
                                        @RequestParam("photoSize") PhotoSizeEnum photoSize,
                                        @RequestParam("image") Part image) throws IOException {
    
            if (log.isTraceEnabled()) 
                log.trace("uploadPhoto. accountId=" + accountId + " petId=" + petId + " photoId=" + photoId + " photoSize=" + photoSize);
    
            PetPhoto petPhoto = petDao.savePetPhoto(accountId, petId, photoId, photoSize, image);
    
            Map<String, Object> map = GsonUtils.wrapWithKeypath(petPhoto, "petPhoto");
            return map;
        }
    

    服务器响应 JSON(注意与映射设置对应的“petPhoto”的 keyPath):

    {
        petPhoto =     {
            accountId = 4ebee3469ae2d8adf983c561;
            contentType = "image/png";
            filename = "4ebee3469ae2d8adf983c561_4ec0983d036463d900841f09_3FED4959-1042-4D8B-91A8-76AA873851A3";
            id = 4ee2e80203646ecd096d5201;
            petId = 4ec0983d036463d900841f09;
            photoId = "3FED4959-1042-4D8B-91A8-76AA873851A3";
        };
    }
    

    代表:

    - (void) objectLoader:(RKObjectLoader*)objectLoader didLoadObject:(id)object {
    
        if ([objectLoader wasSentToResourcePath:@"/pet/uploadPhoto"]) {
           PAPetPhoto *photo = (PAPetPhoto*)object;
        }
    }
    

    【讨论】:

    • 我在我的登录页面上尝试了这个,并到达了它向指定路由发送请求的地步。但是即使我输入了正确的参数(电子邮件和密码),登录总是失败。我怀疑参数设置没有通过,但我不确定是什么原因。如果我使用 RKClient post:params: 方法,它工作正常。 :(
    猜你喜欢
    • 2012-07-19
    • 2019-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 2017-11-03
    • 1970-01-01
    • 2011-11-25
    相关资源
    最近更新 更多