Pergunta

Em um aplicativo que estou escrevendo, tenho um código como este:

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

NSURL* url = [NSURL URLWithString:myurl];

[ws openURL:url];

A principal diferença é que meuurl vem de algum lugar fora do meu controle.Observe o %d no URL que não está totalmente correto e significa que URLWithString falha, retornando nada.

Qual é a maneira "correta" de lidar com isso?Preciso analisar a string e codificar corretamente os argumentos?Ou existe algum método inteligente no Cocoa que faz todo o trabalho duro para mim?

Foi útil?

Solução

Não tenho certeza se é exatamente isso que você está procurando, mas existe um método em NSString que irá limpar uma URL:

stringByAddingPercentEscapesUsingEncoding:

Outras dicas

Acho que o comportamento aqui está correto, porque %d não é um componente válido de uma URL (% é o escape, mas espera que dois caracteres hexadecimais o sigam).

Você não pode simplesmente codificar o URL conforme fornecido a você, porque isso também codificaria os /s e ?s, o que você não deseja.

Então, a questão é: qual é o comportamento correto aqui?

Talvez você queira que ele seja transformado em...

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

(ou seja,o % é codificado para a versão codificada de % em uma URL, então quando o método obtém a entrada, ele vê a como sendo definido como %d)

Não creio que exista alguma função de biblioteca que faça esse tipo de coisa por você, já que não existe uma maneira "correta" de fazer isso.A única coisa correta que você pode fazer é retornar uma mensagem de erro dizendo que o URL que você recebeu é inválido (assim como URLWithString é)


Se você quiser tentar manipular a entrada, acho que precisará pesquisar no URL quaisquer símbolos % que não sejam imediatamente seguidos por dois caracteres hexadecimais e, nesse caso, substituir % por %25.Isso deve ser bem possível com uma expressão regular, embora eu suspeite que possa haver algumas complexidades adicionais se seus URLs começarem a conter versões codificadas de caracteres fora do conjunto de caracteres ASCII.

Infelizmente, você precisa ser mais inteligente do que o fornecido pela Apple:

stringByAddingPercentEscapesUsingEncoding:

Isso escapará de todos os caracteres de URL inválidos para que "http://foo.com/hey%20dude/", que é válido, se torne "http://foo.com/hey%2520dud/", que não é o que queremos .

De acordo com a documentação da Apple: http://developer.apple.com/library/mac/documentation/CoreFOundation/Reference/CFURLRef/Reference/reference.html#//apple_ref/c/func/CFURLCreateStringByAddingPercentEscapes

Eu criei uma categoria NSURL que faz a coisa certa e funciona com strings estranhas, como aquelas com codificação parcial (ou seja,"http://foo.com/hey cara/i%20do%20it/").

Aqui está o código:

@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

Funciona bem com strings UTF8 codificadas e ASCII.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top