Bart Jacobs
Bart Jacobs

Reputation: 9082

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)?

Upvotes: 4

Views: 6836

Answers (3)

nh32rg
nh32rg

Reputation: 1482

You can just do what the code in datwalk's answer is doing without modifying the underlying AFNetworking code. Use AFNetworking to create a path that includes URL parameters:

NSDictionary *mutableParameters = [[NSMutableDictionary alloc] initWithObjectsAndKeys:@"csv",@"format", @"0",@"level", @"2013-10-25", @"keydate", nil];

NSString *urlPath = [NSString stringWithFormat:@"applications/%@/Planning?%@", name, AFQueryStringFromParametersWithEncoding(mutableParameters, NSUTF8StringEncoding)];

NSString *apiFunctionPath = [urlPath stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

[self putPath:apiFunctionPath
   parameters:nil
      success:^(AFHTTPRequestOperation *operation, id XML) {
          NSLog(@"%@",XML);
      }
      failure:^(AFHTTPRequestOperation *operation, NSError *error) {
          NSLog(@"%@",error);
      }];

Upvotes: 3

Jeff Sorrentino
Jeff Sorrentino

Reputation: 21

For the case of my API, changing the encoding of the AFHTTPClient object solved the issue:

myAFHTTPClient.parameterEncoding = AFJSONParameterEncoding;

Upvotes: 1

datwelk
datwelk

Reputation: 1037

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

Upvotes: 4

Related Questions