Losing a / when converting from NSURL to NSURLRequest

匿名 (未验证) 提交于 2019-12-03 01:48:02

问题:

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!

回答1:

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 = @"foo@example.com"; 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]; 


回答2:

EDIT 1 I was getting the problem as described. But missed it in my output. (hence the down vote :-( ) So have removed the code I put up as an answer.

*Edit 2

But related to my comments here is some code apple use to get a NSURLRequest,

NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.apple.com/"]                     cachePolicy:NSURLRequestUseProtocolCachePolicy                 timeoutInterval:60.0];       

@Dave DeLong: I notice in the Apple "URL Loading System Program Guide" the example creating a connection and request does not use any escaping. The Url it uses is from a NSURL URLWithString:



回答3:

I fixed it, this is what I had to do:

NSString *urlString = [NSString stringWithFormat:@"/SetLeaderUrl.json?leader_email=%@&url=%@",localEmail,urlToPublish]; urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]; urlString = [NSString stringWithFormat:@"%@%@%@",scheme,host,urlString]; NSURL *url = [[NSURL alloc] initWithString:urlString]; NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url]; 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!