Потеря / при преобразовании из NSURL в NSURLRequest - PullRequest
10 голосов
/ 24 марта 2011

Я делаю сообщение HTTP в своем приложении для iphone, и одним из параметров, которые я отправляю на сервер, является 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 ]

12 голосов
/ 24 марта 2011

Вы не будете в процентах экранировать значения запроса, прежде чем подставлять их в строку. Я только что провёл небольшой тест и обнаружил, что если установить urlToPublish на «http://example.com",», то NSURL преобразует его в «http: /example.com».

Это потому, что значение запроса содержит специальные символы, что означает, что вам нужно добавить процентные экранированные символы. По крайней мере, вы можете использовать посредственные -[NSString stringByAddingPercentEscapesUsingEncoding:] с NSASCIIStringEncoding. Намного лучше было бы использовать другой (и более полный) механизм побега, такой как тот, который я предлагаю в этом посте .


В этом случае 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];

И тогда он правильно создаст ваш URL.


Вот еще один способ сделать это (и сделать это правильно ). Перейдите на мою страницу github и загрузите файлы 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];
0 голосов
/ 24 марта 2011

Я исправил это, вот что мне нужно было сделать:

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];
0 голосов
/ 24 марта 2011

РЕДАКТИРОВАТЬ 1 Я получил проблему, как описано. Но пропустил это в моем выводе. (отсюда и голосование вниз :-() Поэтому удалили код, который я выложил в ответ.

* Редактировать 2

Но в связи с моими комментариями здесь приведен код, используемый Apple для получения NSURLRequest,

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

@ Дэйв Делонг: Я заметил в Apple " Руководство по программе загрузки URL-адресов ", пример создания соединения и запроса не использует экранирование Используемый URL-адрес взят из NSURL URLWithString:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...