Respostas:
Escapar dos personagens que você quer é um pouco mais de trabalho.
Código de exemplo
iOS7 e superior:
NSString *unescaped = @"http://www";
NSString *escapedString = [unescaped stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
NSLog(@"escapedString: %@", escapedString);
Saída NSLog:
escapedString: http% 3A% 2F% 2Fwww
A seguir, são úteis conjuntos de caracteres de codificação de URL:
URLFragmentAllowedCharacterSet "#%<>[\]^`{|}
URLHostAllowedCharacterSet "#%/<>?@\^`{|}
URLPasswordAllowedCharacterSet "#%/:<>?@[\]^`{|}
URLPathAllowedCharacterSet "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet "#%<>[\]^`{|}
URLUserAllowedCharacterSet "#%/:<>?@[\]^`
Criando um conjunto de caracteres combinando todos os itens acima:
NSCharacterSet *URLCombinedCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@" \"#%/:<>?@[\\]^`{|}"] invertedSet];
Criando um Base64
No caso do conjunto de caracteres Base64:
NSCharacterSet *URLBase64CharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@"/+=\n"] invertedSet];
Para o Swift 3.0:
var escapedString = originalString.addingPercentEncoding(withAllowedCharacters:.urlHostAllowed)
Para Swift 2.x:
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
Nota: stringByAddingPercentEncodingWithAllowedCharacters
também codificará caracteres UTF-8 que precisam de codificação.
Antes do iOS7, use o Core Foundation
usando o Core Foundation With ARC:
NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef) unescaped,
NULL,
CFSTR("!*'();:@&=+$,/?%#[]\" "),
kCFStringEncodingUTF8));
Usando o Core Foundation Without ARC:
NSString *escapedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)unescaped,
NULL,
CFSTR("!*'();:@&=+$,/?%#[]\" "),
kCFStringEncodingUTF8);
Nota: -stringByAddingPercentEscapesUsingEncoding
não produzirá a codificação correta; nesse caso, não codificará nada que retorne a mesma string.
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding
codifica 14 caracteres:
`#% ^ {} [] | \" <> mais o caractere de espaço como porcentagem de escape.
testString:
" `~!@#$%^&*()_+-={}[]|\\:;\"'<,>.?/AZaz"
encodedString:
"%20%60~!@%23$%25%5E&*()_+-=%7B%7D%5B%5D%7C%5C:;%22'%3C,%3E.?/AZaz"
Nota: considere se esse conjunto de caracteres atende às suas necessidades; caso contrário, altere-os conforme necessário.
Caracteres RFC 3986 que exigem codificação (% adicionado, pois é o caractere de prefixo de codificação):
"! # $ & '() * +, /:; =? @ []%"
Alguns "caracteres não reservados" também são codificados:
"\ n \ r \"% -. <> \ ^ _ `{|} ~"
-stringByAddingPercentEscapesUsingEncoding
método NSString .
stringByAddingPercentEscapesUsingEncoding
comportamento descolado . Ele codifica apenas '&' e '=' ou algo ridículo assim.
NSString
com characterSetWithCharactersInString
, leve o inverso com invertedSet
e use-o com stringByAddingPercentEncodingWithAllowedCharacters
. Para um exemplo, veja esta resposta SO .
É chamado de codificação de URL . Mais aqui .
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,
NULL,
(CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(encoding));
}
CFURLCreateStringByAddingPercentEscapes()
está obsoleto. Use em [NSString stringByAddingPercentEncodingWithAllowedCharacters:]
vez disso.
Esta não é a minha solução. Alguém escreveu no stackoverflow, mas eu esqueci como.
De alguma forma, essa solução funciona "bem". Ele lida com caracteres diacríticos, chineses e praticamente qualquer outra coisa.
- (NSString *) URLEncodedString {
NSMutableString * output = [NSMutableString string];
const char * source = [self UTF8String];
int sourceLen = strlen(source);
for (int i = 0; i < sourceLen; ++i) {
const unsigned char thisChar = (const unsigned char)source[i];
if (false && thisChar == ' '){
[output appendString:@"+"];
} else if (thisChar == '.' || thisChar == '-' || thisChar == '_' || thisChar == '~' ||
(thisChar >= 'a' && thisChar <= 'z') ||
(thisChar >= 'A' && thisChar <= 'Z') ||
(thisChar >= '0' && thisChar <= '9')) {
[output appendFormat:@"%c", thisChar];
} else {
[output appendFormat:@"%%%02X", thisChar];
}
}
return output;
}
Se alguém me disser quem escreveu esse código, eu realmente aprecio isso. Basicamente, ele tem algumas explicações sobre por que essa string codificada decodifica exatamente como deseja.
Eu modifiquei um pouco a solução dele. Eu gosto de espaço a ser representado com% 20 em vez de +. Isso é tudo.
NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(NUL,(CFStringRef)@"parameter",NULL,(CFStringRef)@"!*'();@&+$,/?%#[]~=_-.:",kCFStringEncodingUTF8 );
NSURL * url = [[NSURL alloc] initWithString:[@"address here" stringByAppendingFormat:@"?cid=%@",encodedString, nil]];
Isso pode funcionar no ARC do Objetivo C.Use CFBridgingRelease para converter um objeto no estilo Core Foundation como um objeto Objective-C e transferir a propriedade do objeto para o ARC. Consulte a Função CFBridgingRelease aqui.
+ (NSString *)encodeUrlString:(NSString *)string {
return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes
(kCFAllocatorDefault,
(__bridge CFStringRef)string,
NULL,
CFSTR("!*'();:@&=+$,/?%#[]"),
kCFStringEncodingUTF8)
);}
IOS rápido:
Apenas para informação: Eu usei isso:
extension String {
func urlEncode() -> CFString {
return CFURLCreateStringByAddingPercentEscapes(
nil,
self,
nil,
"!*'();:@&=+$,/?%#[]",
CFStringBuiltInEncodings.UTF8.rawValue
)
}
}// end extension String
Aqui está o que eu uso. Observe que você precisa usar o@autoreleasepool
recurso ou o programa pode travar ou bloquear o IDE. Eu tive que reiniciar meu IDE três vezes até perceber a correção. Parece que este código é compatível com ARC.
Esta pergunta já foi feita muitas vezes, e muitas respostas foram dadas, mas infelizmente todas as selecionadas (e algumas sugeridas) estão erradas.
Aqui está a sequência de teste que eu usei: This is my 123+ test & test2. Got it?!
Estes são meus métodos de classe Objective C ++:
static NSString * urlDecode(NSString *stringToDecode) {
NSString *result = [stringToDecode stringByReplacingOccurrencesOfString:@"+" withString:@" "];
result = [result stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return result;
}
static NSString * urlEncode(NSString *stringToEncode) {
@autoreleasepool {
NSString *result = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)stringToEncode,
NULL,
(CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
kCFStringEncodingUTF8
));
result = [result stringByReplacingOccurrencesOfString:@"%20" withString:@"+"];
return result;
}
}
O Google implementa isso na Google Toolbox for Mac . Portanto, esse é um bom lugar para saber como eles estão fazendo isso. Outra opção é incluir a caixa de ferramentas e usar sua implementação.
Confira a implementação aqui . (Que se resume exatamente ao que as pessoas estão postando aqui).
É assim que estou fazendo isso rapidamente.
extension String {
func encodeURIComponent() -> String {
return self.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
}
func decodeURIComponent() -> String {
return self.componentsSeparatedByString("+").joinWithSeparator(" ").stringByRemovingPercentEncoding!
}
}
// use o método de instância NSString assim:
+ (NSString *)encodeURIComponent:(NSString *)string
{
NSString *s = [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return s;
}
+ (NSString *)decodeURIComponent:(NSString *)string
{
NSString *s = [string stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return s;
}
lembre-se, você deve codificar ou decodificar apenas o valor do parâmetro, e não todo o URL solicitado.
int strLength = 0;
NSString *urlStr = @"http://www";
NSLog(@" urlStr : %@", urlStr );
NSMutableString *mutableUrlStr = [urlStr mutableCopy];
NSLog(@" mutableUrlStr : %@", mutableUrlStr );
strLength = [mutableUrlStr length];
[mutableUrlStr replaceOccurrencesOfString:@":" withString:@"%3A" options:NSCaseInsensitiveSearch range:NSMakeRange(0, strLength)];
NSLog(@" mutableUrlStr : %@", mutableUrlStr );
strLength = [mutableUrlStr length];
[mutableUrlStr replaceOccurrencesOfString:@"/" withString:@"%2F" options:NSCaseInsensitiveSearch range:NSMakeRange(0, strLength)];
NSLog(@" mutableUrlStr : %@", mutableUrlStr );
ùÕ9y^VêÏÊEØ®.ú/V÷ÅÖêú2Èh~
- nenhuma das soluções abaixo parece resolver isso!