从NSURL转换为NSURLRequest时丢失/

时间:2011-03-23 22:26:47

标签: iphone objective-c cocoa-touch

我正在我的iphone应用程序中执行HTTP Post,并且我发送到服务器的其中一个参数是URL。问题是当我从NSURL转换为NSURLRequest时,字符串http://www.slashdot.org变为http:/www.slashdot.org(缺少正斜杠之一)

有办法解决这个问题吗?

这是我正在使用的代码:

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];

我已经使用NSLog查看它丢失'/'的位置,它位于第四行:

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

感谢您花时间阅读!

3 个答案:

答案 0 :(得分:12)

在将查询值替换为字符串之前,您不会将查询值转换为百分比。我刚做了一点测试,发现如果我将urlToPublish设置为“http://example.com”,那么NSURL会将其转换为“http:/example.com”。

这是因为查询值包含特殊字符,这意味着您需要添加百分比转义。至少,您可以将-[NSString stringByAddingPercentEscapesUsingEncoding:]NSASCIIStringEncoding一起使用。更好的方法是使用不同的(并且更完整的)转义机制,例如我建议的in this post


在这种情况下,stringByAddingPercentEscapesUsingEncoding:不起作用,因为它是一种非常糟糕的方法。它适用于包含模型,这意味着您必须告诉它您希望百分比编码的字符。 (在引擎盖下,它只是调用CFURLCreateStringByAddingPercentEscapes())这个函数基本上要求你提供一个字符串来表示允许百分比编码的每个字符(据我理解的功能)。你真正想要的是一个独家模型:逃避除了[这一小部分字符]之外的一切。我上面链接的功能就是这样,你可以这样使用它:

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];

然后它会正确构建您的网址。


这是你可以做到这一点的另一种方式(并且正确)。转到my github page并下载“DDURLBuilder.h”和“DDURLBuilder.m”,然后构建您的URL:

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];

答案 1 :(得分:-2)

编辑1 我按照描述得到了问题。但在我的输出中错过了它。 (因此投票:-() 所以删除了我提出的代码作为答案。

* 编辑2

但与我的评论相关的是苹果用来获取NSURLRequest的一些代码,

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

@Dave DeLong:我注意到在Apple“URL Loading System Program Guide”中创建连接和请求的示例不使用任何转义。它使用的网址来自 NSURL URLWithString:

答案 2 :(得分:-4)

我修好了,这就是我必须做的事情:

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];