POST with URL parameters and JSON body in AFNetworking
Asked Answered
T

2

6

I'd like to make a POST call that has both URL parameters and a JSON body:

URL http://example.com/register?apikey=mykey
JSON { "field" : "value"}

How can I use two different serializers at the same time with AFNNetworking? Here's my code with the URL parameters missing:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager POST:@"http://example.com/register" parameters:json success:^(AFHTTPRequestOperation *operation, id   responseObject) {
Tiddly answered 4/4, 2014 at 0:56 Comment(0)
F
3

I make a post method

/**
 *  Services gateway
 *  Method  get response from server
 *  @parameter              -> object: request josn object ,apiName: api endpoint
 *  @returm                 -> void
 *  @compilationHandler     -> success: status of api, response: respose from server, error: error handling
 */
+ (void)getDataWithObject:(NSDictionary *)object onAPI:(NSString *)apiName withController:(UIViewController*)controller
                         :(void(^)(BOOL success,id response,NSError *error))compilationHandler {


    controller = controller;
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

    // set request type to json
    manager.requestSerializer = [AFJSONRequestSerializer serializer];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];


    // post request to server
    [manager POST:apiName parameters:object success:^(AFHTTPRequestOperation *operation, id responseObject) {

        // NSError *error;
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:responseObject
                                                           options:0
                                                             error:&error];

        //NSString *JSONString = [[NSString alloc] initWithBytes:[jsonData bytes] length:[jsonData length] encoding:NSUTF8StringEncoding];
        //// 

        // check the status of API
        NSDictionary *dict = responseObject;
        NSString *statusOfApi = [[NSString alloc]initWithFormat:@"%@"
                                 ,[dict objectForKey:@"OK"]];

        // IF Status is OK -> 1 so complete the handler
        if ([statusOfApi isEqualToString:@"1"] ) {

            [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
            compilationHandler(TRUE,responseObject,nil);

        } else {

            [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

            NSArray *errorMessages = [responseObject objectForKey:@"messages"];
            NSString *message = [errorMessages objectAtIndex:0];

            [Utilities showAlertViewWithTitle:apiName message:message];

            compilationHandler(FALSE,responseObject,nil);
        }

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

        NSString *message = [NSString stringWithFormat:@"%@",[error localizedDescription]];
        NSLog(@"Message is %@", message);

        NSString *errorMessage = [NSString stringWithFormat:@"%@",[error localizedDescription]];
        if (!([message rangeOfString:@"The request timed out."].location == NSNotFound)) {
            [Utilities showAlertViewWithTitle:apiName message:errorMessage];
        }

        compilationHandler(FALSE,errorMessage,nil);
    }];

    // For internet reachibility check if changes its state
    [self checkInternetReachibility:manager];
}

**for Example when we call the Service **

  // calling service gateway API
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                 "field",@"value",
                                 nil];
        [self getDataWithObject:dict onAPI:KGet_Preferences  withController:(UIViewController*)controller :^(BOOL success, id response, NSError *error) {

            if( success ) {
                NSMutableDictionary *data = [[response valueForKey:@"data"] valueForKey:@"preferences"];
                compilationHandler(success,data,error);
            } else {
                compilationHandler(success,nil,error);
            }
        }];
Fibroid answered 19/2, 2016 at 5:27 Comment(2)
Maybe I am missing something, but I don't see how it answers the question. The question is to how post parameters partially in body of HTTP request, and partially in URL. If we use AFHTTPRequestOperationManager and POST, by default, all parameters will be put in the body of the request by AFNetworking.Dispassion
It doesn't answer the question. In your method you use only JSON body and don't use URI parameters.Marlinmarline
D
0

I believe there is no automatic way of doing it. However, there is a simple way of achieving it manually:

- (NSMutableURLRequest *)someRequestWithBaseURL:(NSString *)baseUrl
                                          method:(NSString *)method
                                            path:(NSString *)path
                                      uriParameters:(NSDictionary *)uriParameters
                                  bodyParameters:(NSDictionary *)bodyParameters

NSURL *url = [NSURL URLWithString:path relativeToURL:[NSURL URLWithString:baseUrl]];

AFHTTPRequestSerializer *httpRequestSerializer = [AFJSONRequestSerializer serializerWithWritingOptions:0]

NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithDictionary:bodyParameters];

if ([httpRequestSerializer.HTTPMethodsEncodingParametersInURI containsObject:method]) {
    [parameters addEntriesFromDictionary:uriParameters];
} else {
    NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
    // For urlEncodedString, check https://mcmap.net/q/224720/-creating-url-query-parameters-from-nsdictionary-objects-in-objectivec
    urlComponents.percentEncodedQuery = [uriParameters urlEncodedString];
    url = [urlComponents URL];
}

NSError *error;
NSURLRequest *request = [httpRequestSerializer requestWithMethod:method
                                                       URLString:[url absoluteString]
                                                      parameters:parameters
                                                           error:&error];
Dispassion answered 8/11, 2015 at 19:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.