Sending a JSON via POST in NSURLRequest

29,482

since you try to submit a HTTP POST header like

json={"user":{"username":"%@","password":"%@"}},

this example is fully qualified to end up in confusion.

It's a mixture of application/x-www-form-urlencoded for the whole body and application/json for the value.

Maybe a way to resolve this:

You'll probably need to adjust that HTTP header:

 [request setValue:@"application/x-www-form-urlencoded" 
forHTTPHeaderField:@"Content-Type"];

due to an encoding of the JSON part (value) of the HTTP body:

[request setHTTPBody:[[jsonPostBody stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]
                      dataUsingEncoding:NSUTF8StringEncoding 
                   allowLossyConversion:YES]];    

where stringByAddingPercentEscapesUsingEncoding is objective c jabberwocky for the PHP equivalent urlencode.

HTH

Share:
29,482
Maverick1st
Author by

Maverick1st

SOreadytohelp

Updated on November 18, 2020

Comments

  • Maverick1st
    Maverick1st over 3 years

    I have a problem with sending a JSON to a Server with REST API. This is the code i use:

    NSString *jsonPostBody = [NSString stringWithFormat:@"'json' = '{\"user\":{\"username\":"
                              "\"%@\""
                              ",\"password\":"
                              "\"%@\""
                              "}}'",
                              [username stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
                              [password stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];       
    NSData *postData = [jsonPostBody dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
    NSString *apiPathParams = [NSString stringWithFormat:@"%@",
                               @"getUser"
                               ];
    
    NSURL *url = [NSURL URLWithString:[[apiPath retain] stringByAppendingString:apiPathParams]];    
    NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url
                                                           cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
                                                       timeoutInterval:180.0];
    [request setHTTPMethod:@"POST"];
    [request setHTTPBody:postData];
    NSString* postDataLengthString = [[NSString alloc] initWithFormat:@"%d", [postData length]];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request setValue:postDataLengthString forHTTPHeaderField:@"Content-Length"];
    [self internalRequest:request];
    

    This is what the API would look like, if it was a html form:

    <form method="post" action="someAPI-URL">
    <input name="json" value="{"user":...}" />
    </form>
    

    This is what my POST Data looks like when i add it to the request:

    json={"user":{"username":"someUser","password":"somePassword"}}
    

    For a reason I don't know the POST Data does not arrive at the server. Have i done something wrong with the formatting of the dataString? How exactly must i format my dataString so that it matches the String a form as shown above would deliver to the server?

    Any help would be highly appreciated.

    P.S. I would rather not use ASIHttpRequest, since i took over the project from somebody else an every other request works fine, except this post-request. So changing this whole bulk to an other connection framework would be very time consuming.

    Here is the internalRequest Method's sourcecode

    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:req delegate:self];
    NSMutableDictionary *di = [NSMutableDictionary dictionaryWithObject:[[NSMutableData alloc] init] forKey:@"receivedData"];   
    [di setObject:[NSString stringWithFormat:@"%i",identifier] forKey:@"identifier"];
    if (delegate == nil) 
    { 
        delegate = self;         
    }
    [di setObject:delegate forKey:@"delegate"];
    
    CFDictionaryAddValue(connectionToInfoMapping, connection, di)
    
  • Maverick1st
    Maverick1st over 12 years
    Well, since JSON is nothing more than a special String Representation of a certain context which can be transformed to Dictionarys and Arrays very easily I don't think this will make a difference. Especially since i used POST Requests earlier without a JSON framework. But I'll give it a try. May be it works :)
  • Maverick1st
    Maverick1st over 12 years
    You are my hero of the day. Works like a charm. No i only have to mess up the guy who gave me the interface description... :)