Открытие нестандартного URL-адреса в приложении Cocoa

StackOverflow https://stackoverflow.com/questions/45898

  •  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-адрес:

stringByAddingPercentEscapesUsingEncoding:

Другие советы

Я думаю, что поведение здесь правильное, поскольку %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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top