2

I am trying to post an object with an attached file.

 NSMutableURLRequest *request =
            [objectManager multipartFormRequestWithObject:reqDocObj
                                                   method:RKRequestMethodPOST
                                                     path:@"syncDocument.json"
                                               parameters:nil
                                constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
                                    [formData appendPartWithFileData:UIImagePNGRepresentation([UIImage imageNamed:@"graybox.png"])
                                                                name:@"image"
                                                            fileName:@"some_file"
                                                            mimeType:@"image/jpeg"];

            }];



RKObjectRequestOperation *operation =
            [objectManager
             objectRequestOperationWithRequest:request
                                       success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {


                                       }  
                                    failure:^(RKObjectRequestOperation *operation, NSError *error) {
                                                          NSLog(@"WS: errore operazione di richiesta %@",error);


                                        }  
             ];  


            [objectManager enqueueObjectRequestOperation:operation];

The objectManager is configured as:

    [objectManager setAcceptHeaderWithMIMEType:RKMIMETypeJSON];
    [objectManager setRequestSerializationMIMEType:RKMIMETypeJSON];
    objectManager.requestSerializationMIMEType = RKMIMETypeJSON;

[EDIT]

My mapepd object is SynchDocObj:

requestDocMapping = [RKObjectMapping mappingForClass:[SynchDocObj class]];
[requestDocMapping addAttributeMappingsFromDictionary:mappingDocDict];

The problem is:

1) In the RKlogs, the request.body = null and the JSON object is put into the form-data

2) The server cannot decode the body because it is null

My question is:

1) Am I sending the JSON object in the wrong way?

2) If yes, how can I send a JSON object with a file upload, i.e. as a multipart request? Regards!

[SOLUTION]

Following the suggestion of the answer, I think the solution is 1) retrieve the mapped object from the form-data and not the body ; 2) OR post a nil object and putting a JSON string within the form-data.

gdm
  • 7,647
  • 3
  • 41
  • 71
  • I'm not sure you can send JSON and a file. The file is supported by form-URL encoded format, not JSON. – Wain Dec 17 '13 at 20:35
  • So you are saying that, in RestKit, it is not possible doing something like this http://stackoverflow.com/questions/9081079/rest-http-post-multipart-with-json – gdm Dec 18 '13 at 08:54
  • That's different from what your question suggests. Is that what you want (form encoded request with JSON in one part). That can be done, it just takes a few steps... – Wain Dec 18 '13 at 10:56
  • Yes I would do that... – gdm Dec 18 '13 at 10:58

2 Answers2

3

This:

[objectManager setRequestSerializationMIMEType:RKMIMETypeJSON];
objectManager.requestSerializationMIMEType = RKMIMETypeJSON;

is 2 different ways of saying the same thing - and you don't want to have either of them. You need to send the request as form URL encoded (the default value).

The easiest thing to do is to use the same form as in your current code to create the request, generate the JSON earlier and then use appendPartWithFormData:name: to add it to the request (just before you add the file).

To generate the JSON you can use RestKit (RKMappingOperation) or you can just create a dictionary / array of content and then use NSJSONSerialization to serialise that object to be added to the request.

Wain
  • 118,658
  • 15
  • 128
  • 151
  • could you tell me how to use the mapping? I have a mapped object SynchObj. – gdm Dec 18 '13 at 11:26
  • Is it a managed object or plain? If managed you must supply a `dataSource` to the mapping operation... – Wain Dec 18 '13 at 11:45
  • plain..but I think there i no need to do what you suggest. In fact, in the form-data I have all the mapped object... – gdm Dec 18 '13 at 11:50
  • With your current code RestKit is creating the JSON, but you need it to create a form encoded POST, so you need to create the JSON separately. – Wain Dec 18 '13 at 11:53
  • Yes you are right. I think I will delete the question....thank you for your time, indeed! – gdm Dec 18 '13 at 12:05
  • I think it's a valid question to leave open. – Wain Dec 18 '13 at 14:20
0

Analyze my code, it works like a charm:

RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:[FilledExamCard defineMapping] objectClass:[MappedClassName class] rootKeyPath:nil method:RKRequestMethodPUT];

    NSData *jsonPayload = [self getJSONpayloadFromObject:mappedClassObject requestDescriptor:requestDescriptor];

    NSURL *baseURL = [NSURL URLWithString:[ZDR_BASE_URL stringByAppendingString:@"PutExamCards"]];

    AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:baseURL];

    [RKMIMETypeSerialization registerClass:[RKNSJSONSerialization class] forMIMEType:@"text/plain"];
    [client setDefaultHeader:@"Accept" value:@"text/plain"];

    RKObjectManager *objectManager = [[RKObjectManager alloc] initWithHTTPClient:client];
    [objectManager setRequestSerializationMIMEType: RKMIMETypeJSON];
    [objectManager addRequestDescriptor:requestDescriptor];

    NSMutableURLRequest *request = [objectManager multipartFormRequestWithObject:nil method:RKRequestMethodPUT path:@"" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {

        // Name may vary depending from server settings
        [formData appendPartWithFormData:jsonPayload name:@"model"];
    }];


    RKObjectRequestOperation *operation = [objectManager objectRequestOperationWithRequest:request success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {

        // Process data 

    } failure:^(RKObjectRequestOperation *operation, NSError *error) {

        // An error occurred

    }];

-(NSData*)getJSONpayloadFromObject:(NSObject*)object requestDescriptor:(RKRequestDescriptor*)requestDescriptor
{
    NSDictionary *paramObject = [RKObjectParameterization parametersWithObject:object requestDescriptor:requestDescriptor error:nil];

    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:paramObject options:NSJSONWritingPrettyPrinted error:&error];

    return jsonData;
}
Henadzi Rabkin
  • 6,834
  • 3
  • 32
  • 39