Открытие нестандартного URL-адреса в приложении Cocoa
-
09-06-2019 - |
Вопрос
В приложении, которое я пишу, у меня есть такой код:
NSWorkspace* ws = [NSWorkspace sharedWorkspace];
NSString* myurl = @"http://www.somewebsite.com/method?a=%d";
NSURL* url = [NSURL URLWithString:myurl];
[ws openURL:url];
Основное отличие в том, что Мьюрл приходит откуда-то вне моего контроля.Обратите внимание на %d в URL-адресе, который не совсем верен и означает, что URLWithString завершается с ошибкой, возвращая ноль.
Каков «правильный» способ справиться с этим?Нужно ли мне анализировать строку и правильно кодировать аргументы?Или есть какой-нибудь хитрый метод в Cocoa, который сделает всю тяжелую работу за меня?
Решение
Я не уверен, что это именно то, что вы ищете, но в NSString есть метод, который очищает URL-адрес:
Другие советы
Я думаю, что поведение здесь правильное, поскольку %d не является допустимым компонентом URL-адреса (% — это escape-символ, но ожидается, что за ним будут следовать два шестнадцатеричных символа).
Вы не можете просто URL-адрес закодировать предоставленный вам URL-адрес, потому что это также закодирует /s и ?s, что вам не нужно.
Итак, вопрос в том, какое здесь правильное поведение?
Возможно, вы захотите превратить его в...
http://www.somewebsite.com/method?a=%25d
(т.е.% кодируется в закодированную версию % в URL-адресе, поэтому, когда метод получает входные данные, он видит, что для a установлено значение %d)
Я не думаю, что существует какая-либо библиотечная функция, которая могла бы сделать это за вас, поскольку не существует «правильного» способа сделать это.Единственное правильное, что вы можете сделать, это вернуть сообщение об ошибке, в котором говорится, что предоставленный вам URL-адрес недействителен (как и URLWithString).
Если вы хотите попытаться обработать ввод, я думаю, вам нужно будет найти в URL-адресе любые символы %, за которыми сразу не следуют два шестнадцатеричных символа, а затем в этом случае заменить % на %25.Это вполне возможно с регулярным выражением, хотя я подозреваю, что могут возникнуть некоторые дополнительные сложности, если ваши URL-адреса начнут содержать закодированные версии символов за пределами набора символов ASCII.
К сожалению, вам нужно быть умнее, чем предлагает Apple:
stringByAddingPercentEscapesUsingEncoding:
Это позволит избежать всех недопустимых символов URL-адреса, и действительный адрес «http://foo.com/hey%20dude/» станет «http://foo.com/hey%2520dud/», а это не то, что нам нужно. .
Согласно документации Apple: http://developer.apple.com/library/mac/documentation/CoreFOundation/Reference/CFURLRef/Reference/reference.html#//apple_ref/c/func/CFURLCreateStringByAddingPercentEscapes
Я создал категорию NSURL, которая работает правильно и работает с нечетными строками, например, с частичным кодированием (т.«http://foo.com/эй, чувак/i%20do%20it/»).
Вот код:
@interface NSURL (SmartEncoding)
+ (NSURL *)smartURLWithString:(NSString *)str;
@end
@implementation NSURL (SmartEncoding)
+ (NSURL *)smartURLWithString:(NSString *)str
{
CFStringRef preprocessed = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (CFStringRef)str, CFSTR(""), kCFStringEncodingUTF8);
if (!preprocessed)
preprocessed = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (CFStringRef)str, CFSTR(""), kCFStringEncodingASCII);
if (!preprocessed)
return [NSURL URLWithString:str];
CFStringRef sanitized = CFURLCreateStringByAddingPercentEscapes(NULL, preprocessed, NULL, NULL, kCFStringEncodingUTF8);
CFRelease(preprocessed);
NSURL *result = (NSURL*)CFURLCreateWithString(NULL, sanitized, NULL);
CFRelease(sanitized);
return [result autorelease];
}
@end
Он отлично работает со строками в кодировке UTF8 и ASCII.