回答:
必要な文字をエスケープすることはもう少し仕事です。
コード例
iOS7以降:
NSString *unescaped = @"http://www";
NSString *escapedString = [unescaped stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
NSLog(@"escapedString: %@", escapedString);
NSLog出力:
escapedString:http%3A%2F%2Fwww
以下は、有用なURLエンコード文字セットです。
URLFragmentAllowedCharacterSet "#%<>[\]^`{|}
URLHostAllowedCharacterSet "#%/<>?@\^`{|}
URLPasswordAllowedCharacterSet "#%/:<>?@[\]^`{|}
URLPathAllowedCharacterSet "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet "#%<>[\]^`{|}
URLUserAllowedCharacterSet "#%/:<>?@[\]^`
上記のすべてを組み合わせたキャラクターセットの作成:
NSCharacterSet *URLCombinedCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@" \"#%/:<>?@[\\]^`{|}"] invertedSet];
Base64の作成
Base64文字セットの場合:
NSCharacterSet *URLBase64CharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@"/+=\n"] invertedSet];
Swift 3.0の場合:
var escapedString = originalString.addingPercentEncoding(withAllowedCharacters:.urlHostAllowed)
Swift 2.xの場合:
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
注:stringByAddingPercentEncodingWithAllowedCharacters
エンコードが必要なUTF-8文字もエンコードします。
iOS7より前のバージョンでは、
ARCでCore Foundation を使用してCore Foundation を使用しています。
NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef) unescaped,
NULL,
CFSTR("!*'();:@&=+$,/?%#[]\" "),
kCFStringEncodingUTF8));
ARCなしでCore Foundationを使用する:
NSString *escapedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)unescaped,
NULL,
CFSTR("!*'();:@&=+$,/?%#[]\" "),
kCFStringEncodingUTF8);
注意: -stringByAddingPercentEscapesUsingEncoding
は正しいエンコードを生成しません。この場合、同じ文字列を返すものはエンコードされません。
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding
14文字をエンコードします。
`#%^ {} [] | \" <>プラスパーセントエスケープとしてのスペース文字。
testString:
" `~!@#$%^&*()_+-={}[]|\\:;\"'<,>.?/AZaz"
encryptedString:
"%20%60~!@%23$%25%5E&*()_+-=%7B%7D%5B%5D%7C%5C:;%22'%3C,%3E.?/AZaz"
注:この文字セットがニーズを満たしているかどうかを検討し、そうでない場合は必要に応じて変更してください。
エンコーディングを必要とするRFC 3986文字(エンコーディングプレフィックス文字であるため、%が追加されます):
「!#$& '()* +、/:; =?@ []%」
一部の「予約されていない文字」はさらにエンコードされます。
"\ n \ r \"%-。<> \ ^ _ `{|}〜"
-stringByAddingPercentEscapesUsingEncoding
メソッドを使用できることに注意してください。
stringByAddingPercentEscapesUsingEncoding
行動を覚えています。「&」と「=」、またはそのようなとんでもないものだけをエンコードします。
これはURLエンコーディングと呼ばれます。詳細はこちら。
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,
NULL,
(CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(encoding));
}
CFURLCreateStringByAddingPercentEscapes()
廃止予定です。[NSString stringByAddingPercentEncodingWithAllowedCharacters:]
代わりに使用してください。
これは私の解決策ではありません。他の誰かがスタックオーバーフローで書いたが、私はその方法を忘れてしまった。
どういうわけか、このソリューションは「うまく」機能します。発音区別符号、漢字、その他ほとんどすべてを処理します。
- (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;
}
誰かがこのコードを書いた人を教えてくれれば、本当に感謝します。基本的に彼は、このエンコードされた文字列が望みどおりに正確にデコードされる理由を説明しています。
私は彼の解決策を少し修正しました。+ではなく%20でスペースを表すのが好きです。それで全部です。
NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(NUL,(CFStringRef)@"parameter",NULL,(CFStringRef)@"!*'();@&+$,/?%#[]~=_-.:",kCFStringEncodingUTF8 );
NSURL * url = [[NSURL alloc] initWithString:[@"address here" stringByAppendingFormat:@"?cid=%@",encodedString, nil]];
これはObjective C ARCで機能します。CFBridgingReleaseを使用して、Core FoundationスタイルのオブジェクトをObjective-Cオブジェクトとしてキャストし、オブジェクトの所有権をARCに転送します。ここで、関数CFBridgingReleaseを参照してください。
+ (NSString *)encodeUrlString:(NSString *)string {
return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes
(kCFAllocatorDefault,
(__bridge CFStringRef)string,
NULL,
CFSTR("!*'();:@&=+$,/?%#[]"),
kCFStringEncodingUTF8)
);}
これが私が使うものです。あなたが使用しなければならないことに注意してください@autoreleasepool
機能。そうしないと、プログラムがクラッシュしたり、IDEがロックアップしたりする可能性があります。修正に気付くまで、IDEを3回再起動する必要がありました。このコードはARCに準拠しているようです。
この質問は何度も尋ねられ、多くの回答が出されましたが、残念なことに、選択されたすべての質問(および他のいくつかの提案)は間違っています。
これが私が使ったテスト文字列です: This is my 123+ test & test2. Got it?!
これらは私の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;
}
}
これは私が迅速にこれを行う方法です。
extension String {
func encodeURIComponent() -> String {
return self.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
}
func decodeURIComponent() -> String {
return self.componentsSeparatedByString("+").joinWithSeparator(" ").stringByRemovingPercentEncoding!
}
}
//次のようにNSStringインスタンスメソッドを使用します:
+ (NSString *)encodeURIComponent:(NSString *)string
{
NSString *s = [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return s;
}
+ (NSString *)decodeURIComponent:(NSString *)string
{
NSString *s = [string stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return s;
}
要求するすべてのURLではなく、パラメータ値のエンコードまたはデコードのみを行う必要があることを覚えておいてください。
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~
以下のような暗号化された文字列を持っています-以下の解決策のどれもこれに対処していないようです!