丢失/当从NSURL转换为NSURLRequest时 [英] Losing a / when converting from NSURL to NSURLRequest

查看:98
本文介绍了丢失/当从NSURL转换为NSURLRequest时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的iphone应用程序做一个HTTP邮件,我发送到服务器的一个参数是一个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:@httphost: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];感谢您抽出宝贵的时间阅读!



< h2_lin>解决方案

在将查询值替换为字符串之前,不是百分比。我只是做了一点测试,发现如果我设置 urlToPublish 到http://example.com,然后 NSURL 会将其转换为http:/example.com。



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






在这种情况下, stringByAddingPercentEscapesUsingEncoding:不工作,因为它是一个相当糟糕的方法。它适用于包含模型,这意味着您必须告诉它要编码的字符。 (底层,它只是调用 CFURLCreateStringByAddingPercentEscapes() )这个函数基本上要求你一个字符串,代表每个字符允许percent-encode(我理解函数)。你真正想要的是一个独占模型:escape除了这个小字符集。上面链接的函数就是这样,你可以这样使用它:

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

然后会正确建立您的网址。






这是另一种可以做到这一点的方法(正确)。转到我的github页面,下载DDURLBuilder.h和DDURLBuilder.m,然后构建您的网址如下:

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


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!

解决方案

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

这篇关于丢失/当从NSURL转换为NSURLRequest时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆