Append data to a POST NSURLRequest Append data to a POST NSURLRequest ios ios

Append data to a POST NSURLRequest


If you don't wish to use 3rd party classes then the following is how you set the post body...

NSURL *aUrl = [NSURL URLWithString:@"http://www.apple.com/"];NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl                                         cachePolicy:NSURLRequestUseProtocolCachePolicy                                     timeoutInterval:60.0];[request setHTTPMethod:@"POST"];NSString *postString = @"company=Locassa&quality=AWESOME!";[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];NSURLConnection *connection= [[NSURLConnection alloc] initWithRequest:request                                                              delegate:self];

Simply append your key/value pair to the post string


All the changes to the NSMutableURLRequest must be made before calling NSURLConnection.

I see this problem as I copy and paste the code above and run TCPMon and see the request is GET instead of the expected POST.

NSURL *aUrl = [NSURL URLWithString:@"http://www.apple.com/"];NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl                                     cachePolicy:NSURLRequestUseProtocolCachePolicy                                 timeoutInterval:60.0];[request setHTTPMethod:@"POST"];NSString *postString = @"company=Locassa&quality=AWESOME!";[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];NSURLConnection *connection= [[NSURLConnection alloc] initWithRequest:request                                                          delegate:self];


The previous posts about forming POST requests are largely correct (add the parameters to the body, not the URL). But if there is any chance of the input data containing any reserved characters (e.g. spaces, ampersand, plus sign), then you will want to handle these reserved characters. Namely, you should percent-escape the input.

//create body of the requestNSString *userid = ...NSString *encodedUserid = [self percentEscapeString:userid];NSString *postString    = [NSString stringWithFormat:@"userid=%@", encodedUserid];NSData   *postBody      = [postString dataUsingEncoding:NSUTF8StringEncoding];//initialize a request from urlNSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];[request setHTTPBody:postBody];[request setHTTPMethod:@"POST"];[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];//initialize a connection from request, any way you want to, e.g.NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

Where the precentEscapeString method is defined as follows:

- (NSString *)percentEscapeString:(NSString *)string{    NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,                                                                                 (CFStringRef)string,                                                                                 (CFStringRef)@" ",                                                                                 (CFStringRef)@":/?@!$&'()*+,;=",                                                                                 kCFStringEncodingUTF8));    return [result stringByReplacingOccurrencesOfString:@" " withString:@"+"];}

Note, there was a promising NSString method, stringByAddingPercentEscapesUsingEncoding (now deprecated), that does something very similar, but resist the temptation to use that. It handles some characters (e.g. the space character), but not some of the others (e.g. the + or & characters).

The contemporary equivalent is stringByAddingPercentEncodingWithAllowedCharacters, but, again, don't be tempted to use URLQueryAllowedCharacterSet, as that also allows + and & pass unescaped. Those two characters are permitted within the broader "query", but if those characters appear within a value within a query, they must escaped. Technically, you can either use URLQueryAllowedCharacterSet to build a mutable character set and remove a few of the characters that they've included in there, or build your own character set from scratch.

For example, if you look at Alamofire's parameter encoding, they take URLQueryAllowedCharacterSet and then remove generalDelimitersToEncode (which includes the characters #, [, ], and @, but because of a historical bug in some old web servers, neither ? nor /) and subDelimitersToEncode (i.e. !, $, &, ', (, ), *, +, ,, ;, and =). This is correct implementation (though you could debate the removal of ? and /), though pretty convoluted. Perhaps CFURLCreateStringByAddingPercentEscapes is more direct/efficient.