Risposte:
Per sfuggire ai personaggi che vuoi è un po 'più di lavoro.
Codice di esempio
iOS7 e versioni successive:
NSString *unescaped = @"http://www";
NSString *escapedString = [unescaped stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
NSLog(@"escapedString: %@", escapedString);
Uscita NSLog:
escapedString: http% 3A% 2F% 2Fwww
Di seguito sono riportati utili set di caratteri di codifica URL:
URLFragmentAllowedCharacterSet "#%<>[\]^`{|}
URLHostAllowedCharacterSet "#%/<>?@\^`{|}
URLPasswordAllowedCharacterSet "#%/:<>?@[\]^`{|}
URLPathAllowedCharacterSet "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet "#%<>[\]^`{|}
URLUserAllowedCharacterSet "#%/:<>?@[\]^`
Creazione di un set di caratteri che combina tutto quanto sopra:
NSCharacterSet *URLCombinedCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@" \"#%/:<>?@[\\]^`{|}"] invertedSet];
Creazione di una Base64
Nel caso del set di caratteri Base64:
NSCharacterSet *URLBase64CharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@"/+=\n"] invertedSet];
Per Swift 3.0:
var escapedString = originalString.addingPercentEncoding(withAllowedCharacters:.urlHostAllowed)
Per Swift 2.x:
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
Nota: stringByAddingPercentEncodingWithAllowedCharacters
codificherà anche i caratteri UTF-8 che richiedono la codifica.
Pre iOS7 utilizza Core Foundation
utilizzando Core Foundation con ARC:
NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef) unescaped,
NULL,
CFSTR("!*'();:@&=+$,/?%#[]\" "),
kCFStringEncodingUTF8));
Utilizzo di Core Foundation senza ARC:
NSString *escapedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)unescaped,
NULL,
CFSTR("!*'();:@&=+$,/?%#[]\" "),
kCFStringEncodingUTF8);
Nota: -stringByAddingPercentEscapesUsingEncoding
non produrrà la codifica corretta, in questo caso non codificherà nulla restituendo la stessa stringa.
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding
codifica 14 caratteri:
`#% ^ {} [] | \" <> più il carattere spazio come percentuale di escape.
testString:
" `~!@#$%^&*()_+-={}[]|\\:;\"'<,>.?/AZaz"
encodedString:
"%20%60~!@%23$%25%5E&*()_+-=%7B%7D%5B%5D%7C%5C:;%22'%3C,%3E.?/AZaz"
Nota: considera se questo set di personaggi soddisfa le tue esigenze, se non cambiarle secondo necessità.
Caratteri RFC 3986 che richiedono codifica (% aggiunta poiché è il prefisso di codifica):
"# $ & '() * +, /:;!? = @ []%"
Alcuni "caratteri senza prenotazione" sono inoltre codificati:
"\ n \ r \"% -. <> \ ^ _ `{|} ~"
-stringByAddingPercentEscapesUsingEncoding
metodo NSString .
stringByAddingPercentEscapesUsingEncoding
comportamento funky . Codifica solo '&' e '=' o qualcosa di ridicolo come quello.
NSString
con characterSetWithCharactersInString
, prendi l'inverso con invertedSet
e usalo con stringByAddingPercentEncodingWithAllowedCharacters
. Per un esempio vedere questa risposta SO .
Si chiama codifica URL . Più qui .
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,
NULL,
(CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(encoding));
}
CFURLCreateStringByAddingPercentEscapes()
è deprecato. Usa [NSString stringByAddingPercentEncodingWithAllowedCharacters:]
invece.
Questa non è la mia soluzione. Qualcun altro ha scritto in StackOverflow ma ho dimenticato come.
In qualche modo questa soluzione funziona "bene". Gestisce i caratteri diacritici, cinesi e praticamente qualsiasi altra 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;
}
Se qualcuno mi dicesse chi ha scritto questo codice, lo apprezzerei davvero. Fondamentalmente ha qualche spiegazione sul perché questa stringa codificata decodificherà esattamente come desidera.
Ho modificato un po 'la sua soluzione. Mi piace che lo spazio sia rappresentato con% 20 anziché +. È tutto.
NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(NUL,(CFStringRef)@"parameter",NULL,(CFStringRef)@"!*'();@&+$,/?%#[]~=_-.:",kCFStringEncodingUTF8 );
NSURL * url = [[NSURL alloc] initWithString:[@"address here" stringByAppendingFormat:@"?cid=%@",encodedString, nil]];
Questo può funzionare in Objective C ARC.Usare CFBridgingRelease per lanciare un oggetto in stile Core Foundation come oggetto Objective-C e trasferire la proprietà dell'oggetto in ARC . Vedere Funzione CFBridgingRelease qui.
+ (NSString *)encodeUrlString:(NSString *)string {
return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes
(kCFAllocatorDefault,
(__bridge CFStringRef)string,
NULL,
CFSTR("!*'();:@&=+$,/?%#[]"),
kCFStringEncodingUTF8)
);}
Swift iOS:
Solo per informazione: ho usato questo:
extension String {
func urlEncode() -> CFString {
return CFURLCreateStringByAddingPercentEscapes(
nil,
self,
nil,
"!*'();:@&=+$,/?%#[]",
CFStringBuiltInEncodings.UTF8.rawValue
)
}
}// end extension String
Ecco cosa uso. Nota che devi usare la @autoreleasepool
funzione o il programma potrebbe bloccarsi o bloccare l'IDE. Ho dovuto riavviare il mio IDE tre volte fino a quando ho realizzato la correzione. Sembra che questo codice sia conforme ARC.
Questa domanda è stata posta molte volte e sono state fornite molte risposte, ma purtroppo tutte quelle selezionate (e alcune altre suggerite) sono sbagliate.
Ecco la stringa di test che ho usato: This is my 123+ test & test2. Got it?!
Questi sono i miei metodi di 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;
}
}
Google lo implementa nella sua Google Toolbox per Mac . Quindi è un buon posto per raggiungere il picco su come lo stanno facendo. Un'altra opzione è quella di includere la Casella degli strumenti e utilizzare la loro implementazione.
Controlla l'implementazione qui . (Il che si riduce esattamente a ciò che le persone hanno pubblicato qui).
Questo è come lo sto facendo rapidamente.
extension String {
func encodeURIComponent() -> String {
return self.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
}
func decodeURIComponent() -> String {
return self.componentsSeparatedByString("+").joinWithSeparator(" ").stringByRemovingPercentEncoding!
}
}
// usa il metodo dell'istanza NSString in questo modo:
+ (NSString *)encodeURIComponent:(NSString *)string
{
NSString *s = [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return s;
}
+ (NSString *)decodeURIComponent:(NSString *)string
{
NSString *s = [string stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return s;
}
ricorda, dovresti solo codificare o decodificare il valore del tuo parametro, non tutto l'URL richiesto.
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~
- nessuna delle soluzioni di seguito sembra risolverla!