7

Problem

I've been trying to post to the server with a multiform request that includes an image attachment. I haven't had trouble getting the image to the server, it is the other information that is not sending correctly.

Details

I'm using object mapping to configure several different attributes when receiving objects from the server:

//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;

Then, when it comes time to post a photo I update configurations as follows:

 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"];

Participants are people tagged with the photo. Here is how I'm posting it, similar to this 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;
    }];

The server is receiving the image as planned, and actually does receive the 'created' and 'participants' unfortunately it's in a strange format that the server doesn't understand. It includes line breaks and such participants (\n 19843589323 \n created: \n 3-31-2012 00:00 (something like that, I will update when I have access to the logs.

I will give you any extra info you need. Would offer reputation for it if I had enough to do so ;)

Rob Caraway
  • 3,856
  • 3
  • 30
  • 37
  • Do you mean a POST with Content-type `multipart/form-data`? Do you insist on using RestKit for this? – leo Sep 26 '12 at 15:16
  • I would prefer to stick with Restkit, and I do believe a multipart/form-data is right.. but could you elaborate? – Rob Caraway Sep 26 '12 at 15:24
  • Can't help you with RestKit, but if it's not a requirement, many other solutions are available. This morning I put a gist online for playing with multipart/form-data, have a look [https://gist.github.com/3786554](https://gist.github.com/3786554) – leo Sep 26 '12 at 15:32
  • I know its been awhile but I decided to give yours a shot because I just can't get what I need out of Restkit. You have a method called NSData randomWithLength... where is that coming from? – Rob Caraway Oct 25 '12 at 19:33
  • Also you have a escapeforURL method that isn't there either – Rob Caraway Oct 25 '12 at 19:49
  • Good to hear. I updated the gist ([https://gist.github.com/3786554](https://gist.github.com/3786554)) to be more self-contained. The example at the top should demonstrate how you can upload an image as `multipart/form-data`. – leo Oct 25 '12 at 20:49

2 Answers2

14

In RestKit 0.20.0-pre3, RKObjectManager does have method multipartFormRequestWithObject:method:path:parameters:constructingBodyWithBlock:

pkananen
  • 1,325
  • 1
  • 11
  • 23
11

An example of this task can be found at the 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
Robertibiris
  • 844
  • 8
  • 15