8

I am using the following code,

NSString *jsonD = [NSString stringWithFormat:@"rawJson=%@",[fbUserInfo jsonUTF8String]];
NSData *myRequestData = [jsonD dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
                                                           cachePolicy:policy timeoutInterval:20.0];

[ request setHTTPMethod: @"POST" ];
[request setValue:[NSString stringWithFormat:@"%d", [myRequestData length]] forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[ request setHTTPBody: myRequestData ];

In this code I have the date 2013-06-29T18:33:17+0000. The problem is that my server receiving date as 2013-06-29T18:33:17 0000. See the space. I don't know why this is happening.

Imran Qadir Baksh - Baloch
  • 32,612
  • 68
  • 179
  • 322

4 Answers4

5

Just because you specify the encoding header does not mean the NSURLRequest will actually perform said encoding.

The CFURLCreateStringByAddingPercentEscapes function can URL-encode your strings for you.

If you don't care about the encoding and just want to send simple strings, I suggest you skip the encoding entirely and use the "text/plain" content type.

Another option would be to use JSON instead of form encoding ("application/json"). JSON is much easier to use, both on the server side and on the client side. Cocoa has builtin support for JSON.

EDIT: Now that I read your code again, I see that you name your variable suggesting that the data is already JSON. If so, the solution is to use the "application/json" content type and make sure the server understands and decodes this properly.

Krumelur
  • 31,081
  • 7
  • 77
  • 119
2

If you need to have the ' ' -> '+' substitution, you need to do it on your own.

See: Objective-c iPhone percent encode a string? for the code to do the conversion.


Update

OK, based on your comment, here is some additional information. Based on old handling of query strings, '+' characters are turned into ' ' characters.

It was enshrined into old JavaScript, CGI, and PHP handing of URLs.

Microsoft even has a buggy example demonstrating it.

You can avoid the problem by always converting '+' to '%2B' and ' ' to '%20'.

Community
  • 1
  • 1
Jeffery Thomas
  • 42,202
  • 8
  • 92
  • 117
1

The AFNetworking library solves it thusly:

static NSString * AFPercentEscapedQueryStringPairMemberFromStringWithEncoding(NSString *string, NSStringEncoding encoding) {
    static NSString * const kAFCharactersToBeEscaped = @":/?&=;+!@#$()~',*";
    static NSString * const kAFCharactersToLeaveUnescaped = @"[].";

    return (__bridge_transfer  NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, (__bridge CFStringRef)kAFCharactersToLeaveUnescaped, (__bridge CFStringRef)kAFCharactersToBeEscaped, CFStringConvertNSStringEncodingToEncoding(encoding));
}
FluffulousChimp
  • 9,157
  • 3
  • 35
  • 42
  • Would you care to elaborate? – FluffulousChimp Jul 03 '13 at 10:16
  • Yes, sorry that was kind of mean. My point is that a third party lib is not the solution to all problems. This does solves (I guess) the problem, but by avoiding it altogether. I didn't downvote though, as it does provide a solution to the problem :) – Guillaume Algis Jul 03 '13 at 10:21
  • I agree; I was showing the implementation only as an example of how others have solved it, not to advocate for using that library _in toto_. – FluffulousChimp Jul 03 '13 at 10:58
1

As @Krumelur suggested,The CFURLCreateStringByAddingPercentEscapes function can URL-encode your strings for you. And Here is the code.

static NSString * CTPercentEscapedQueryStringValueFromStringWithEncoding(NSString *string, NSStringEncoding encoding) {
    return (__bridge_transfer  NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, (__bridge CFStringRef)kCharactersToBeEscapedInQueryString, CFStringConvertNSStringEncodingToEncoding(encoding));
}

And Complete solution : To get encoded url from parameters use below code.

/**
 get parameterized url from url and query parameters.
 */
+(NSString *)getParameterizedUrl:(NSString *)url withParameters:(NSDictionary *)queryDictionary
{
    NSMutableArray *mutablePairs = [NSMutableArray array];
    for (NSString *key in queryDictionary) {
        [mutablePairs addObject:[NSString stringWithFormat:@"%@=%@", CTPercentEscapedQueryStringKeyFromStringWithEncoding(key, NSUTF8StringEncoding), CTPercentEscapedQueryStringValueFromStringWithEncoding(queryDictionary[key], NSUTF8StringEncoding)]];
    }

    return [[NSString alloc]initWithFormat:@"%@?%@",url,[mutablePairs componentsJoinedByString:@"&"]];
}

static NSString * const kCharactersToBeEscapedInQueryString = @":/?&=;+!@#$()',*";

static NSString * CTPercentEscapedQueryStringKeyFromStringWithEncoding(NSString *string, NSStringEncoding encoding) {
    static NSString * const kCharactersToLeaveUnescapedInQueryStringPairKey = @"[].";

    return (__bridge_transfer  NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, (__bridge CFStringRef)kCharactersToLeaveUnescapedInQueryStringPairKey, (__bridge CFStringRef)kCharactersToBeEscapedInQueryString, CFStringConvertNSStringEncodingToEncoding(encoding));
}

static NSString * CTPercentEscapedQueryStringValueFromStringWithEncoding(NSString *string, NSStringEncoding encoding) {
    return (__bridge_transfer  NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, (__bridge CFStringRef)kCharactersToBeEscapedInQueryString, CFStringConvertNSStringEncodingToEncoding(encoding));
}

And use in your code as

NSString *url = [self getParameterizedUrl:@"http://www.example.com" withParameters:self.params];

Note : params here is dictionary.

Giru Bhai
  • 14,370
  • 5
  • 46
  • 74