次のようなNSString
があります。
http://www.
しかし、私はそれをに変換したい:
http%3A%2F%2Fwww.
これどうやってするの?
必要な文字をエスケープするには、もう少し手間がかかります。
サンプルコード
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以前はCore Foundationを使用
ARCで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"
encodedString:
"%20%60~!@%23$%25%5E&*()_+-=%7B%7D%5B%5D%7C%5C:;%22'%3C,%3E.?/AZaz"
注:この文字セットがニーズに合っているかどうかを検討し、必要に応じて変更しないでください。
エンコードが必要なRFC 3986文字(エンコードプレフィックス文字であるため、%が追加されます):
「!#$& '()* +、/:; =?@ []%」
一部の「予約されていない文字」はさらにエンコードされます。
"\ n\r \"%-。<>\^ _ `{|}〜"
RL encoding と呼ばれます。もっと こちら 。
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,
NULL,
(CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(encoding));
}
これは私の解決策ではありません。他の誰かがstackoverflowで書いたが、私はその方法を忘れてしまった。
どういうわけか、このソリューションは「うまく」機能します。発音区別記号、漢字、その他ほとんどすべてを処理します。
- (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に転送します。 Function CFBridgingRelease hereを参照してください。
+ (NSString *)encodeUrlString:(NSString *)string {
return CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes
(kCFAllocatorDefault,
(__bridge CFStringRef)string,
NULL,
CFSTR("!*'();:@&=+$,/?%#[]"),
kCFStringEncodingUTF8)
);}
Swift iOS:
情報提供のみ:これを使用しました:
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);
str
を自分でリリースまたは自動リリースする必要があります。
Googleは、これを Mac用Googleツールボックス で実装しています。だから、彼らはそれをやっている方法をピークにするのに良い場所です。別のオプションは、ツールボックスを含めて実装を使用することです。
実装をチェックアウトします こちら 。 (これは、人々がここに投稿したものに正確になります)。
これは私がスウィフトでこれをやっている方法です。
extension String {
func encodeURIComponent() -> String {
return self.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
}
func decodeURIComponent() -> String {
return self.componentsSeparatedByString("+").joinWithSeparator(" ").stringByRemovingPercentEncoding!
}
}
ここに私が使用するものがあります。 @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;
}
}