Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Losing a / when converting from NSURL to NSURLRequest

I'm doing an HTTP Post in my iphone app and one of the parameters I send to the server is a URL. The problem is that when I convert from an NSURL to an NSURLRequest, the string http://www.slashdot.org becomes http:/www.slashdot.org (one of the forward slashes is missing)

is there a way around this?

here is the code I'm using:

NSString *host = @"example.host.com";
NSString *urlString = [NSString stringWithFormat:@"/SetLeaderUrl.json?leader_email=%@&url=%@",localEmail,urlToPublish];
NSURL *url = [[NSURL alloc] initWithScheme:@"http" host:host path:urlString];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *jsonString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];

I've used NSLog to see where it loses the '/' and it's on the fourth line:

NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];

thanks for taking the time to read!

like image 786
Lance Avatar asked Mar 23 '11 22:03

Lance


1 Answers

You're not percent-escaping the query values before substituting them in to the string. I just did a little test, and found that if I set urlToPublish to "http://example.com", then NSURL would transform it into "http:/example.com".

This is because the query value contains special characters, which means you need to add percent escapes. At the very least you can use the mediocre -[NSString stringByAddingPercentEscapesUsingEncoding:] with the NSASCIIStringEncoding. Far better would be to use a different (and more complete) escaping mechanism, such as the one I suggest in this post.


In this case, stringByAddingPercentEscapesUsingEncoding: does not work, because it's a pretty lousy method. It works on an inclusive model, which means you have to tell it which characters you want percent encoded. (Under the hood, it's just calling CFURLCreateStringByAddingPercentEscapes()) This function basically asks you for a string that represents every character it's allowed to percent-encode (as I understand the function). What you really want is an exclusive model: escape everything except [this small set of characters]. The function I linked to above does that, and you'd use it like this:

NSString *urlToPublish = [@"http://stackoverflow.com" URLEscapedString_ch];
NSString *host = @"example.host.com";
NSString *urlString = [NSString stringWithFormat:@"/SetLeaderUrl.json?leader_email=%@&url=%@",localEmail,urlToPublish];
NSURL *url = [[NSURL alloc] initWithScheme:@"http" host:host path:urlString];

And then it will build your URL properly.


Here's another way you could do this (and do it correctly). Go to my github page and download "DDURLBuilder.h" and "DDURLBuilder.m", and then build your URL like this:

NSString *localEmail = @"[email protected]";
NSString *urlToPublish = @"http://stackoverflow.com"

DDURLBuilder *b = [DDURLBuilder URLBuilderWithURL:nil];
[b setScheme:@"http"];
[b setHost:@"example.host.com"];
[b setPath:@"SetLeaderUrl.json"];
[b addQueryValue:localEmail forKey:@"leader_email"];
[b addQueryValue:urlToPublish forKey:@"url"];

NSURL *url = [b URL];
like image 100
Dave DeLong Avatar answered Nov 07 '22 23:11

Dave DeLong