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

objective-c macos cocoa

1500 просмотра

3 ответа

46294 Репутация автора

В приложении, которое я пишу, у меня есть такой код:

NSWorkspace* ws = [NSWorkspace sharedWorkspace];
NSString* myurl = @"http://www.somewebsite.com/method?a=%d";

NSURL* url = [NSURL URLWithString:myurl];

[ws openURL:url];

Основное различие заключается в том, что Мюрл приходит откуда-то вне моего контроля. Обратите внимание на% d в URL, который не совсем корректен и означает, что URLWithString завершается ошибкой, возвращая ноль .

Каков «правильный» способ справиться с этим? Нужно ли анализировать строку и правильно кодировать аргументы? Или есть какой-нибудь умный метод в Какао, который делает всю тяжелую работу для меня?

Автор: Stephen Darlington Источник Размещён: 05.09.2008 02:12

Ответы (3)


2 плюса

68978 Репутация автора

Я думаю, что здесь правильное поведение, потому что% d не является допустимым компонентом URL (% - это escape, но ожидается, что за ним следуют два шестнадцатеричных символа).

Вы не можете просто закодировать URL, как вам дано, потому что это также закодирует / s и? S, что вам не нужно.

Итак, вопрос в том, каково здесь правильное поведение?

Возможно, вы хотели бы, чтобы это было превращено в ...

http://www.somewebsite.com/method?a=%25d

(т. е.% кодируется в кодированную версию% в URL, поэтому, когда метод получает входные данные, он видит, что для него установлено значение% d)

Я не думаю, что есть какая-либо библиотечная функция, которая будет делать такие вещи для вас, поскольку нет «правильного» способа сделать это. Единственное правильное, что вы можете сделать, это вернуть сообщение об ошибке, в котором говорится, что указанный вами URL-адрес недействителен (так же, как и URLWithString).


Если вы хотите попытаться обработать ввод, я думаю, вам нужно будет найти в URL любые символы%, за которыми сразу не идут два шестнадцатеричных символа, а затем заменить% на% 25 в этом случае. Это должно быть вполне возможно с помощью регулярного выражения, хотя я подозреваю, что могут возникнуть некоторые дополнительные сложности, если ваши URL-адреса начинают содержать закодированные версии символов вне набора символов ASCII.

Автор: Matt Sheppard Размещён: 05.09.2008 02:18

8 плюса

6013 Репутация автора

Решение

Я не уверен, что это именно то, что вы ищете, но в NSString есть метод, который будет очищать URL:

stringByAddingPercentEscapesUsingEncoding:

Автор: amrox Размещён: 05.09.2008 04:21

1 плюс

932 Репутация автора

К сожалению, вы должны быть умнее, чем 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/hey dude / 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.

Автор: nverinaud Размещён: 29.12.2011 09:18
32x32