-1

How can i URLEncode a NSDictionary so i can send it across AFNetworking.

The code is as follows:

NSMutableDictionary *rus = [[NSMutableDictionary alloc] init];
[rus setValue:@"1211" forKey:@"id"];
[rus setValue:@"33" forKey:@"man"];

How can i Encode this NSDictionary so i can send it across AFNetworking ?

Illep
  • 16,375
  • 46
  • 171
  • 302
  • Look at this [question](http://stackoverflow.com/questions/8356842/how-to-use-nsjsonserialization), serialize it into a `NSData*` object, pass that into `AFHTTPRequestOperation` 's responseSerializer. Think you need to read up a bit more on how to use AFNetworking. – t0mm13b Sep 25 '15 at 19:20
  • I didn't understand that code. Can you kindly elaborate – Illep Sep 25 '15 at 19:24
  • 1. Take your `NSMutableDictionary`. 2. Use the `dataWithJSONObject:options:error:` method. 3. profit (you will have an NSData object at that point) – Rich Tolley Sep 25 '15 at 20:00

2 Answers2

0

Depends how you wish to send your data:

1) @"application/json" in which case you would use [NSJSONSerialization dataWithJSONObject:parameters options:self.writingOptions error:error]

2) @"application/x-www-form-urlencoded" in which case you basically want to create the string: ?id=1211&man=33 from your dictionary rus.

Here's some code, may not be the most efficient by you get the idea:

 NSString *temp;
    int i=0;

    for(NSString *key in options.params.allKeys)
    {
        NSString *value = [options.params objectForKey:key];
        [parameters setObject:value forKey:key];

        if(i==0)
        {
            temp = [NSString stringWithFormat:@"?%@=%@", key,value];
        }
        else
        {
            temp = [NSString stringWithFormat:@"%@&%@=%@", temp, key, value];
        }
    }

Note: may or may not be relevant to you, but my two cents:

I use AFHTTPSessionManager which handles all the details for me including url encoding, so I just pass in the desired dictionary:

    NSMutableDictionary *rus = [[NSMutableDictionary alloc] init];
    [rus setValue:@"1211" forKey:@"id"];
    [rus setValue:@"33" forKey:@"man"];

    [self POST:@"/api/place/nearbysearch" parameters:rus success:^(NSURLSessionDataTask *task, id responseObject) {
            NSLog(@"nearbyPlaces: success");
            [self fetchedPlacesData:responseObject block:block];
            if(task != nil && task.originalRequest != nil)
            {
                NSString *url = [task.originalRequest.URL absoluteString];
                [self saveNearbySearchEvent:url params:params];
            }
        } failure:^(NSURLSessionDataTask *task, NSError *error) {
            NSLog(@"nearbyPlaces: error: %@", error);
            block(self, nil, error);
        }];

AFHTTPSessionManager encapsulates a lot of functionality included serializing the data: AFURLRequestSerialization either as JSON or HTTP Request. In case you interested on what AFHTTPSessionManager actually does here's some detail:

A) HTTP Request Here's the code from AFURLRequestSerialization.m:

- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
                               withParameters:(id)parameters
                                        error:(NSError *__autoreleasing *)error
{
    NSParameterAssert(request);

    NSMutableURLRequest *mutableRequest = [request mutableCopy];

    [self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) {
        if (![request valueForHTTPHeaderField:field]) {
            [mutableRequest setValue:value forHTTPHeaderField:field];
        }
    }];

    if (parameters) {
        NSString *query = nil;
        if (self.queryStringSerialization) {
            NSError *serializationError;
            query = self.queryStringSerialization(request, parameters, &serializationError);

            if (serializationError) {
                if (error) {
                    *error = serializationError;
                }

                return nil;
            }
        } else {
            switch (self.queryStringSerializationStyle) {
                case AFHTTPRequestQueryStringDefaultStyle:
                    query = AFQueryStringFromParametersWithEncoding(parameters, self.stringEncoding);
                    break;
            }
        }

        if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) {
            mutableRequest.URL = [NSURL URLWithString:[[mutableRequest.URL absoluteString] stringByAppendingFormat:mutableRequest.URL.query ? @"&%@" : @"?%@", query]];
        } else {
            if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) {
                [mutableRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
            }
            [mutableRequest setHTTPBody:[query dataUsingEncoding:self.stringEncoding]];
        }
    }

    return mutableRequest;
}

B) JSON

- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
                               withParameters:(id)parameters
                                        error:(NSError *__autoreleasing *)error
{
    NSParameterAssert(request);

    if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) {
        return [super requestBySerializingRequest:request withParameters:parameters error:error];
    }

    NSMutableURLRequest *mutableRequest = [request mutableCopy];

    [self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) {
        if (![request valueForHTTPHeaderField:field]) {
            [mutableRequest setValue:value forHTTPHeaderField:field];
        }
    }];

    if (parameters) {
        if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) {
            [mutableRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
        }

        [mutableRequest setHTTPBody:[NSJSONSerialization dataWithJSONObject:parameters options:self.writingOptions error:error]];
    }

    return mutableRequest;
}
codinpora
  • 11
  • 2
0
NSMutableDictionary *rus = [[NSMutableDictionary alloc] init];
[rus setValue:@"1211" forKey:@"id"];
[rus setValue:@"33" forKey:@"man"];

If you are exchanging JSON data with your server:

NSError *error = nil;
NSData *aRequestData = [NSJSONSerialization dataWithJSONObject:rus options:NSJSONWritingPrettyPrinted error:&error];

if (!error) {
     [urlRequest setHTTPBody:aRequestData];
}

If you are exchanging PLIST data with your server:

[self stringByAppendingQueryParameters:rus appendQuestionMark:NO];

- (NSString *)stringByAppendingQueryParameters:(NSDictionary *)iParameters appendQuestionMark:(BOOL)iAppendQuestionMark {
    BOOL aAppendAmpersand = YES;
    NSMutableString *aWorking = [NSMutableString stringWithString:self];

    if (iAppendQuestionMark) {
        NSRange aQueryBeginning = [self rangeOfString:@"?"];
        if (aQueryBeginning.location == NSNotFound) {
            [aWorking appendString:@"?"];
            aAppendAmpersand = NO;
        }
    } else {
        aAppendAmpersand = NO;  
    }

    for (id aKey in iParameters) {
        id aValue = [iParameters valueForKey:aKey];
        NSString *aKeyStr = [self convertObjectToURLEncodedValue:aKey];

    if (aAppendAmpersand) {
        [aWorking appendString:@"&"];
    } else {
        aAppendAmpersand = YES;
    }

    if ([aValue isKindOfClass:[NSArray class]]) {
        NSArray *aSubParamaters = (NSArray *)aValue;
        BOOL aFirstTime = YES;
        for (id aSubValue in aSubParamaters) {
            NSString *aValueString = [self convertObjectToURLEncodedValue:aSubValue];

            if (!aFirstTime) {
                [aWorking appendString:@"&"];                   
            }
            [aWorking appendString:aKeyStr];
            [aWorking appendString:@"="];
            [aWorking appendString:aValueString];

            aFirstTime = NO;
        }

    } else {
        NSString *aValueString = [self convertObjectToURLEncodedValue:aValue];
        [aWorking appendString:aKeyStr];
        [aWorking appendString:@"="];
        [aWorking appendString:aValueString];           
    }

}

return [NSString stringWithString:aWorking];        
}


- (NSString *)convertObjectToURLEncodedValue:(id)iObject {
    NSString *anIntermediate = nil;

    if ([iObject isKindOfClass:[NSString class]]) {
        anIntermediate = iObject;
    } else if ([iObject respondsToSelector:@selector(stringValue)]) {
        anIntermediate = [iObject stringValue];
    } else {
        anIntermediate = [iObject description];
    }

    NSString *anEncodingString = (__bridge_transfer NSString *)(CFURLCreateStringByAddingPercentEscapes(
                                                                                     NULL,
                                                                                     (__bridge CFStringRef)anIntermediate,
                                                                                     NULL,
                                                                                     (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                                                                     kCFStringEncodingUTF8 ));
    return anEncodingString;
}
Abhinav
  • 37,684
  • 43
  • 191
  • 309