Objective-C y encoding Swift URL

Tengo un NSString como este:

 http://www. 

pero quiero transformarlo a:

 http%3A%2F%2Fwww. 

¿Cómo puedo hacer esto?

Para escapar de los personajes que quieres es un poco más de trabajo.

Código de ejemplo

iOS7 y superior:

 NSString *unescaped = @"http://www"; NSString *escapedString = [unescaped stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]]; NSLog(@"escapedString: %@", escapedString); 

Salida NSLog:

escapedString: http% 3A% 2F% 2Fwww

Los siguientes son útiles conjuntos de caracteres de encoding URL:

 URLFragmentAllowedCharacterSet "#%<>[\]^`{|} URLHostAllowedCharacterSet "#%/<>?@\^`{|} URLPasswordAllowedCharacterSet "#%/:<>?@[\]^`{|} URLPathAllowedCharacterSet "#%;<>?[\]^`{|} URLQueryAllowedCharacterSet "#%<>[\]^`{|} URLUserAllowedCharacterSet "#%/:<>?@[\]^` 

Crear un conjunto de caracteres que combine todo lo anterior:

 NSCharacterSet *URLCombinedCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@" \"#%/:<>?@[\\]^`{|}"] invertedSet]; 

Creando un Base64

En el caso del conjunto de caracteres Base64:

 NSCharacterSet *URLBase64CharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@"/+=\n"] invertedSet]; 

Para Swift 3.0:

 var escapedString = originalString.addingPercentEncoding(withAllowedCharacters:.urlHostAllowed) 

Para Swift 2.x:

 var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet()) 

Nota: stringByAddingPercentEncodingWithAllowedCharacters también codificará los caracteres UTF-8 que necesitan encoding.

Pre iOS7 usa Core Foundation
Usando Core Foundation con ARC:

 NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes( NULL, (__bridge CFStringRef) unescaped, NULL, CFSTR("!*'();:@&=+$,/?%#[]\" "), kCFStringEncodingUTF8)); 

Usando Core Foundation sin ARC:

 NSString *escapedString = (NSString *)CFURLCreateStringByAddingPercentEscapes( NULL, (CFStringRef)unescaped, NULL, CFSTR("!*'();:@&=+$,/?%#[]\" "), kCFStringEncodingUTF8); 

Nota: -stringByAddingPercentEscapesUsingEncoding no producirá la encoding correcta, en este caso no codificará nada que devuelva la misma cadena.

stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding codifica 14 caracteres:

`#% ^ {} [] | \” <> más el carácter de espacio como porcentaje escapado.

TestString:

 " `~!@#$%^&*()_+-={}[]|\\:;\"'<,>.?/AZaz" 

encodedString:

 "%20%60~!@%23$%25%5E&*()_+-=%7B%7D%5B%5D%7C%5C:;%22'%3C,%3E.?/AZaz" 

Nota: considere si este conjunto de caracteres satisface sus necesidades, de lo contrario cámbielos según sea necesario.

RFC 3986 caracteres que requieren encoding (% añadido ya que es el carácter de prefijo de encoding):

“! # $ Y ‘() * +, /:; =? @ []%”

Algunos “caracteres no reservados” están adicionalmente codificados:

“\ n \ r \”% -. <> \ ^ _ `{|} ~”

Se llama encoding URL . Más aquí .

 -(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding { return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self, NULL, (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", CFStringConvertNSStringEncodingToEncoding(encoding)); } 

Esta no es mi solución. Alguien más escribió en stackoverflow pero he olvidado cómo.

De alguna manera, esta solución funciona “bien”. Maneja caracteres diacríticos, chinos y casi cualquier otra cosa.

 - (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; } 

Si alguien me dijera quién escribió este código, realmente lo agradeceré. Básicamente tiene alguna explicación de por qué esta cadena codificada se decodificará exactamente como lo desea.

Modifiqué su solución un poco. Me gusta que el espacio se represente con% 20 en lugar de +. Eso es todo.

  NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(NUL,(CFStringRef)@"parameter",NULL,(CFStringRef)@"!*'();@&+$,/?%#[]~=_-.:",kCFStringEncodingUTF8 ); NSURL * url = [[NSURL alloc] initWithString:[@"address here" stringByAppendingFormat:@"?cid=%@",encodedString, nil]]; 

Esto puede funcionar en Objective C ARC. Utilice CFBridgingRelease para convertir un objeto de Core Foundation al estilo de Objective-C y transferir la propiedad del objeto a ARC. Consulte la función CFBridgingRelease aquí.

 + (NSString *)encodeUrlString:(NSString *)string { return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes (kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, CFSTR("!*'();:@&=+$,/?%#[]"), kCFStringEncodingUTF8) );} 

Swift iOS:

Solo para información: He usado esto:

 extension String { func urlEncode() -> CFString { return CFURLCreateStringByAddingPercentEscapes( nil, self, nil, "!*'();:@&=+$,/?%#[]", CFStringBuiltInEncodings.UTF8.rawValue ) } }// end extension String 
 NSString *str = (NSString *)CFURLCreateStringByAddingPercentEscapes( NULL, (CFStringRef)yourString, NULL, CFSTR("/:"), kCFStringEncodingUTF8); 

Tendrá que soltar o soltar la tira usted mismo.

Google implementa esto en su Google Toolbox para Mac . Entonces ese es un buen lugar para alcanzar el máximo de cómo lo están haciendo. Otra opción es incluir Toolbox y usar su implementación.

Verifique la implementación aquí . (Lo que se reduce a exactamente lo que la gente ha estado publicando aquí).

Así es como lo estoy haciendo rápido.

 extension String { func encodeURIComponent() -> String { return self.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())! } func decodeURIComponent() -> String { return self.componentsSeparatedByString("+").joinWithSeparator(" ").stringByRemovingPercentEncoding! } } 

Esto es lo que uso. Tenga en cuenta que debe usar la función @autoreleasepool o que el progtwig podría bloquear o bloquear el IDE. Tuve que reiniciar mi IDE tres veces hasta que me di cuenta de la solución. Parece que este código es compatible con ARC.

Esta pregunta se ha hecho muchas veces, y se han dado muchas respuestas, pero lamentablemente todas las seleccionadas (y algunas otras sugeridas) son incorrectas.

Aquí está la cadena de prueba que utilicé: This is my 123+ test & test2. Got it?! This is my 123+ test & test2. Got it?!

Estos son mis métodos de clase 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; } } 

// usa el método de instancia de NSString así:

 + (NSString *)encodeURIComponent:(NSString *)string { NSString *s = [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; return s; } + (NSString *)decodeURIComponent:(NSString *)string { NSString *s = [string stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; return s; } 

recuerde, solo debe codificar o decodificar el valor de su parámetro, no todas las URL que solicite.

 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 );