Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AFNetworking: Append parameters as the query string for PUT request

First of all, I realize that for a PUT request the request parameters should be passed in the request body. However, I am working with an API (which I am only consuming, not developing) that expects the request parameters to be appended as the query string for a PUT request.

I am making use of a subclass of AFHTTPClient. For the particular PUT request that I am referring to, I make use of getPath:parameters:success:failure:.

The solution that I have found so far is manually constructing the path variable to include the parameters I want to pass. Of course, this is not ideal and I was wondering if there is another option that is less error prone.

In short, is there a way to send a PUT request using AFHTTPClient (a subclass of) with the passed parameters appended (and encoded) as the query string (just like a GET request)?

like image 429
Bart Jacobs Avatar asked Feb 19 '23 20:02

Bart Jacobs


1 Answers

The getPath:parameters:success:failure method inside AFHTTPClient.m calls requestWithMethod:path:parameters. Inside the latter method, the HTTP method is checked against certain values to decide how to append the parameters to the request. As you can see, by default, the parameters should only be appended to the URL in case of a GET, HEAD or DELETE request. Since you need them to be appended to the URL in case of a PUT request too, modify the requestWithMethod:path:parameters like this:

    - (NSMutableURLRequest *)requestWithMethod:(NSString *)method 
                                      path:(NSString *)path 
                                parameters:(NSDictionary *)parameters 
{   
    NSURL *url = [NSURL URLWithString:path relativeToURL:self.baseURL];
    NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] initWithURL:url] autorelease];
    [request setHTTPMethod:method];
    [request setAllHTTPHeaderFields:self.defaultHeaders];

    if ([method isEqualToString:@"GET"] || [method isEqualToString:@"HEAD"]) {
        [request setHTTPShouldUsePipelining:YES];
    }

    if (parameters) {        
        if ([method isEqualToString:@"GET"] || [method isEqualToString:@"HEAD"] || [method isEqualToString:@"DELETE"] || [method isEqualToString:@"PUT"]) {
            url = [NSURL URLWithString:[[url absoluteString] stringByAppendingFormat:[path rangeOfString:@"?"].location == NSNotFound ? @"?%@" : @"&%@", AFQueryStringFromParametersWithEncoding(parameters, self.stringEncoding)]];
            [request setURL:url];
        } else {
            NSString *charset = (NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(self.stringEncoding));
            switch (self.parameterEncoding) {
                case AFFormURLParameterEncoding:;
                    [request setValue:[NSString stringWithFormat:@"application/x-www-form-urlencoded; charset=%@", charset] forHTTPHeaderField:@"Content-Type"];
                    [request setHTTPBody:[AFQueryStringFromParametersWithEncoding(parameters, self.stringEncoding) dataUsingEncoding:self.stringEncoding]];
                    break;
                case AFJSONParameterEncoding:;
                    [request setValue:[NSString stringWithFormat:@"application/json; charset=%@", charset] forHTTPHeaderField:@"Content-Type"];
                    [request setHTTPBody:[AFJSONStringFromParameters(parameters) dataUsingEncoding:self.stringEncoding]];
                    break;
                case AFPropertyListParameterEncoding:;
                    [request setValue:[NSString stringWithFormat:@"application/x-plist; charset=%@", charset] forHTTPHeaderField:@"Content-Type"];
                    [request setHTTPBody:[AFPropertyListStringFromParameters(parameters) dataUsingEncoding:self.stringEncoding]];
                    break;
            }
        }
    }

    return request;
}
like image 103
datwelk Avatar answered May 07 '23 05:05

datwelk