我正在使用 RestKit 驱动与我的网络服务器的交互。我正在尝试使用路由将事件对象 POST 到服务器,并附有图像。代码如下:
RKObjectManager *manager = [RKObjectManager sharedManager];
RKObjectMapping *map = [self eventMapping];
manager.serializationMIMEType = RKMIMETypeFormURLEncoded;
map.rootKeyPath = @"event";
[manager.mappingProvider setSerializationMapping:map forClass:[Event class]];
[manager.router routeClass:[Event class] toResourcePath:@"/v1/events.json" forMethod:RKRequestMethodPOST];
[manager postObject:event delegate:self block:^(RKObjectLoader *loader){
RKObjectMapping *serMap = [[[RKObjectManager sharedManager] mappingProvider] serializationMappingForClass:[Event class]];
NSError *error = nil;
NSDictionary *d = [[RKObjectSerializer serializerWithObject:event mapping:serMap] serializedObject:&error];
RKParams *p = [RKParams paramsWithDictionary:d];
[p setData:[event imageData] MIMEType:@"image/jpeg" forParam:@"image"];
loader.params = p;
}];
如果我使用序列化的 Event 对象创建 RKParams 的实例,然后添加图像数据并将其指定为 RKObjectLoader 的 params 属性,所有属性将成为一个巨大的序列化字符串。必须有一种方法可以在不进行大量字符串序列化的情况下上传图像。
我也尝试过将 NSData 属性映射到某个属性,一路将 UIImage 转换为 NSData,但 RestKit 提示它无法映射。以前有人这样做过吗?
最佳答案
我做了一些非常相似的事情,结果很好。我知道你的问题是关于为什么 RKObjectSerializer 没有按你期望的方式工作,但也许它与你的设置有关。我正在发布我的代码,以提供一个有效的示例。也就是说,在阅读 RKObjectSerializer 文档后,我不明白为什么你不能以这种方式初始化 RKParams 而不是像我在我的示例中那样直接设置它们。
路由器设置:
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"];
帖子:(请注意,因为我在 block 中构建了所有参数,所以我的对象只是一个虚拟实例,用于触发正确的路由和映射器)。
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";
};
}
委托(delegate):
- (void) objectLoader:(RKObjectLoader*)objectLoader didLoadObject:(id)object {
if ([objectLoader wasSentToResourcePath:@"/pet/uploadPhoto"]) {
PAPetPhoto *photo = (PAPetPhoto*)object;
}
}
关于objective-c - RestKit 图片上传,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8438170/