带有图像的 Restkit MultiForm 帖子

Posted

技术标签:

【中文标题】带有图像的 Restkit MultiForm 帖子【英文标题】:Restkit MultiForm Post with an Image 【发布时间】:2012-09-26 15:01:58 【问题描述】:

问题

我一直在尝试使用包含图像附件的多格式请求发布到服务器。我没有遇到问题将图像发送到服务器,这是未正确发送的其他信息。

详情

我在从服务器接收对象时使用对象映射来配置几个不同的属性:

//Using a custom class to map object I receive to
RKObjectMapping * memoryMapper = [RKObjectMapping mappingForClass:[MemoContent class]];
[memoryMapper mapAttributes:@"created", @"user", @"participants", @"tags", @"text", @"kind", @"video", @"location", nil];
[memoryMapper mapKeyPath:@"_id" toAttribute:@"memoryID"];

//MediaMapper handles the data needed for the Image attachments
RKObjectMapping * mediaMapper = [RKObjectMapping mappingForClass:[MemoMedia class]];
[mediaMapper mapKeyPath:@"processed" toAttribute:@"processed"];
[mediaMapper mapKeyPath:@"original" toAttribute:@"original"];
[mediaMapper mapKeyPath:@"mime" toAttribute:@"mimeType"];
[memoryMapper mapKeyPath:@"media" toRelationship:@"rawMedia" withMapping:mediaMapper];

//
[[RKObjectManager sharedManager].mappingProvider setMapping:memoryMapper forKeyPath:@"memories"];
[RKObjectManager sharedManager].serializationMIMEType = RKMIMETypeFormURLEncoded;
[RKObjectManager sharedManager].acceptMIMEType = RKMIMETypeJSON;

然后,当需要发布照片时,我会更新配置如下:

 RKObjectMapping * memoryMapper = [RKObjectMapping mappingForClass:[MemoContent class]];
[memoryMapper mapAttributes:@"created", @"participants",  nil];
[[RKObjectManager sharedManager].mappingProvider setSerializationMapping:memoryMapper forClass:[MemoContent class]];
[[RKObjectManager sharedManager].mappingProvider setMapping:memoryMapper forKeyPath:@"memory"];

参与者是带有照片标签的人。这是我发布的方式,类似于https://github.com/RestKit/RestKit/wiki/Attach-a-File-to-an-RKObjectLoader

   [[RKObjectManager sharedManager] postObject:theMemory usingBlock:^(RKObjectLoader * loader)

    RKObjectMapping* serializationMapping = [[[RKObjectManager sharedManager] mappingProvider] serializationMappingForClass:[MemoContent class]];
    NSLog(@"serializationMapping: %@", serializationMapping);
    loader.delegate = APP; //main app delegate posting, updating
    NSError* error = nil;
    RKObjectSerializer * serializer = [[RKObjectSerializer alloc] initWithObject:theMemory mapping:serializationMapping];
    NSDictionary * dictionary = [serializer serializedObject:&error];  
    RKParams * params = [RKParams paramsWithDictionary:dictionary];
    NSData * imageData = UIImagePNGRepresentation(theMemory.photo); //image data
    [params setData:imageData MIMEType:@"image/png" forParam:@"attachment"];
    loader.params = params;
    loader.serializationMIMEType = RKMIMETypeFormURLEncoded;
    ];

服务器正在按计划接收图像,实际上确实接收了“创建”和“参与者”,不幸的是它的格式很奇怪,服务器无法理解。它包括换行符和诸如participants (\n 19843589323 \n created: \n 3-31-2012 00:00 之类的东西,当我可以访问日志时我会更新。

我会给你任何你需要的额外信息。如果我有足够的能力,我会为它提供声誉;)

【问题讨论】:

你的意思是一个内容类型为multipart/form-data的POST吗?您是否坚持为此使用 RestKit? 我更愿意坚持使用 Restkit,而且我相信 multipart/form-data 是正确的.. 但你能详细说明一下吗? 无法帮助您使用 RestKit,但如果不是必需的,还有许多其他解决方案可用。今天早上我在网上放了一个玩multipart/form-data的要点,看看https://gist.github.com/3786554 我知道已经有一段时间了,但我决定试一试你的,因为我无法从 Restkit 中得到我需要的东西。您有一个名为 NSData randomWithLength 的方法......它来自哪里? 另外你还有一个不存在的 escapeforURL 方法 【参考方案1】:

在RestKit 0.20.0-pre3,RKObjectManager 确实有方法multipartFormRequestWithObject:method:path:parameters:constructingBodyWithBlock:

【讨论】:

我实际上确实最终使用了这种技术,愚蠢的我没有将它添加到接受的答案中。谢谢。【参考方案2】:

可以在RestKit Github page 找到此任务的示例:

Article *article = [Article new];
UIImage *image = [UIImage imageNamed:@"some_image.png"];

// Serialize the Article attributes then attach a file
NSMutableURLRequest *request = [[RKObjectManager sharedManager] multipartFormRequestWithObject:article method:RKRequestMethodPOST path:nil parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) 
    [formData appendPartWithFileData:UIImagePNGRepresentation(image)
                                name:@"article[image]"
                            fileName:@"photo.png"
                            mimeType:@"image/png"];
];

RKObjectRequestOperation *operation = [[RKObjectManager sharedManager] objectRequestOperationWithRequest:request success:nil failure:nil];
[[RKObjectManager sharedManager] enqueueObjectRequestOperation:operation]; // NOTE: Must be enqueued rather than started

【讨论】:

为什么排队而不是开始?

以上是关于带有图像的 Restkit MultiForm 帖子的主要内容,如果未能解决你的问题,请参考以下文章

RestKit CoreData 和 UIImage

RestKit 映射结果已填充,但未设置核心数据实体

restkit 映射嵌套数组为空(带有 json 响应的嵌套 restkit 请求)

带有本地 XML 的 RestKit

RESTKit:带有字典的 RKMappingResult

带有 NSDateFormatter 的 RestKit