Jawaban:
Untuk menghindari karakter yang Anda inginkan adalah sedikit lebih banyak pekerjaan.
Kode contoh
iOS7 dan di atasnya:
NSString *unescaped = @"http://www";
NSString *escapedString = [unescaped stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
NSLog(@"escapedString: %@", escapedString);
Output NSLog:
escapedString: http% 3A% 2F% 2Fwww
Berikut ini adalah set karakter penyandian URL yang berguna:
URLFragmentAllowedCharacterSet "#%<>[\]^`{|}
URLHostAllowedCharacterSet "#%/<>?@\^`{|}
URLPasswordAllowedCharacterSet "#%/:<>?@[\]^`{|}
URLPathAllowedCharacterSet "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet "#%<>[\]^`{|}
URLUserAllowedCharacterSet "#%/:<>?@[\]^`
Membuat rangkaian karakter yang menggabungkan semua hal di atas:
NSCharacterSet *URLCombinedCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@" \"#%/:<>?@[\\]^`{|}"] invertedSet];
Membuat Base64
Dalam kasus Base64 karakter:
NSCharacterSet *URLBase64CharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@"/+=\n"] invertedSet];
Untuk Swift 3.0:
var escapedString = originalString.addingPercentEncoding(withAllowedCharacters:.urlHostAllowed)
Untuk Swift 2.x:
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
Catatan: stringByAddingPercentEncodingWithAllowedCharacters
juga akan menyandikan karakter UTF-8 yang membutuhkan penyandian.
Pra iOS7 menggunakan Core Foundation
Menggunakan Core Foundation With ARC:
NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef) unescaped,
NULL,
CFSTR("!*'();:@&=+$,/?%#[]\" "),
kCFStringEncodingUTF8));
Menggunakan Core Foundation Tanpa ARC:
NSString *escapedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)unescaped,
NULL,
CFSTR("!*'();:@&=+$,/?%#[]\" "),
kCFStringEncodingUTF8);
Catatan: -stringByAddingPercentEscapesUsingEncoding
tidak akan menghasilkan penyandian yang benar, dalam hal ini tidak akan menyandikan apa pun yang mengembalikan string yang sama.
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding
mengkodekan 14 karakter:
`#% ^ {} [] | \" <> ditambah karakter spasi saat persen lolos.
testString:
" `~!@#$%^&*()_+-={}[]|\\:;\"'<,>.?/AZaz"
encodedString:
"%20%60~!@%23$%25%5E&*()_+-=%7B%7D%5B%5D%7C%5C:;%22'%3C,%3E.?/AZaz"
Catatan: pertimbangkan apakah rangkaian karakter ini memenuhi kebutuhan Anda, jika tidak mengubahnya sesuai kebutuhan.
RFC 3986 karakter yang memerlukan pengodean (% ditambahkan karena ini adalah karakter awalan pengodean):
"! # $ & '() * +, /:; =? @ []%"
Beberapa "karakter yang tidak dilindungi" juga disandikan:
"\ n \ r \"% -. <> \ ^ _ `{|} ~"
-stringByAddingPercentEscapesUsingEncoding
metode NSString .
stringByAddingPercentEscapesUsingEncoding
perilaku funky . Itu hanya mengkodekan '&' dan '=' atau sesuatu yang konyol seperti itu.
NSString
dengan characterSetWithCharactersInString
, ambil kebalikannya invertedSet
dan gunakan dengan stringByAddingPercentEncodingWithAllowedCharacters
. Sebagai contoh, lihat jawaban SO ini .
Ini disebut pengkodean URL . Lebih lanjut di sini .
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,
NULL,
(CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(encoding));
}
CFURLCreateStringByAddingPercentEscapes()
sudah ditinggalkan. Gunakan [NSString stringByAddingPercentEncodingWithAllowedCharacters:]
sebagai gantinya.
Ini bukan solusi saya. Orang lain menulis di stackoverflow tetapi saya lupa caranya.
Entah bagaimana solusi ini bekerja "dengan baik". Ini menangani diakritik, karakter Cina, dan hampir semua hal lainnya.
- (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;
}
Jika seseorang memberi tahu saya siapa yang menulis kode ini, saya akan sangat menghargainya. Pada dasarnya ia memiliki beberapa penjelasan mengapa string yang dikodekan ini akan memecahkan kode persis seperti yang diinginkan.
Saya memodifikasi solusinya sedikit. Saya suka ruang diwakili dengan% 20 daripada +. Itu saja.
NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(NUL,(CFStringRef)@"parameter",NULL,(CFStringRef)@"!*'();@&+$,/?%#[]~=_-.:",kCFStringEncodingUTF8 );
NSURL * url = [[NSURL alloc] initWithString:[@"address here" stringByAppendingFormat:@"?cid=%@",encodedString, nil]];
Ini dapat bekerja di Objective C ARC. Gunakan CFBridgingRelease untuk melemparkan objek gaya Core Foundation sebagai objek Objective-C dan mentransfer kepemilikan objek ke ARC. Lihat Fungsi CFBridgingRelease di sini.
+ (NSString *)encodeUrlString:(NSString *)string {
return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes
(kCFAllocatorDefault,
(__bridge CFStringRef)string,
NULL,
CFSTR("!*'();:@&=+$,/?%#[]"),
kCFStringEncodingUTF8)
);}
IOS Swift:
Sekadar Informasi: Saya telah menggunakan ini:
extension String {
func urlEncode() -> CFString {
return CFURLCreateStringByAddingPercentEscapes(
nil,
self,
nil,
"!*'();:@&=+$,/?%#[]",
CFStringBuiltInEncodings.UTF8.rawValue
)
}
}// end extension String
Inilah yang saya gunakan. Catatan Anda harus menggunakan @autoreleasepool
fitur ini atau program mungkin crash atau mengunci IDE. Saya harus me-restart IDE saya tiga kali sampai saya menyadari perbaikannya. Tampaknya kode ini sesuai dengan ARC.
Pertanyaan ini telah ditanyakan berkali-kali, dan banyak jawaban diberikan, tetapi sayangnya semua jawaban yang dipilih (dan beberapa lainnya menyarankan) salah.
Inilah string tes yang saya gunakan: This is my 123+ test & test2. Got it?!
Ini adalah metode kelas Objective C ++ saya:
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 mengimplementasikan ini di Google Toolbox untuk Mac mereka . Jadi itu adalah tempat yang bagus untuk memuncak bagaimana mereka melakukannya. Pilihan lain adalah memasukkan Toolbox dan menggunakan implementasinya.
Lihat implementasinya di sini . (Yang turun persis seperti apa yang orang posting di sini).
Ini adalah bagaimana saya melakukan ini dengan cepat.
extension String {
func encodeURIComponent() -> String {
return self.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
}
func decodeURIComponent() -> String {
return self.componentsSeparatedByString("+").joinWithSeparator(" ").stringByRemovingPercentEncoding!
}
}
// gunakan metode instance NSString seperti ini:
+ (NSString *)encodeURIComponent:(NSString *)string
{
NSString *s = [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return s;
}
+ (NSString *)decodeURIComponent:(NSString *)string
{
NSString *s = [string stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return s;
}
ingat, Anda hanya harus melakukan encode atau decode untuk nilai parameter Anda, tidak semua url yang Anda minta.
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~
- sepertinya tidak ada solusi di bawah ini yang mengatasi masalah ini!