ios9のstringByAddingPercentEscapesUsingEncodingの代替?


112

iOS8以前では、以下を使用できます。

NSString *str = ...; // some URL
NSString *result = [str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

iOS9でstringByAddingPercentEscapesUsingEncoding置き換えられましたstringByAddingPercentEncodingWithAllowedCharacters

NSString *str = ...; // some URL
NSCharacterSet *set = ???; // where to find set for NSUTF8StringEncoding?
NSString *result = [str stringByAddingPercentEncodingWithAllowedCharacters:set];

そして、私の質問は:必要に応じてどこにあるNSCharacterSetNSUTF8StringEncoding)の適切な交換のためにstringByAddingPercentEscapesUsingEncoding

回答:


131

非推奨のメッセージは次のように述べています(鉱山を強調):

代わりにstringByAddingPercentEncodingWithAllowedCharacters(_ :)を使用しますこれは、推奨されるUTF-8エンコーディングを常に使用し、特定のURLコンポーネントまたはサブコンポーネントをエンコードします。各URLコンポーネントまたはサブコンポーネントには、有効な文字に関する異なるルールがあるためです。

したがってNSCharacterSet、引数として適切なものを指定するだけで済みます。幸い、URLにはURLHostAllowedCharacterSet、次のように使用できる非常に便利なクラスメソッドがあります。

let encodedHost = unencodedHost.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())

Swift 3の更新-メソッドは静的プロパティになりますurlHostAllowed

let encodedHost = unencodedHost.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)

ただし、次のことに注意してください。

このメソッドは、URL文字列全体ではなく、URLコンポーネントまたはサブコンポーネント文字列をパーセントエンコードすることを目的としています。


6
また、NSURLComponentsパーセントエンコーディングを処理できるを使用することを強くお勧めします。
Antonio Favata

1
URL文字列全体に何を使用するかについての提案はありますか?
スキルM2

1
@ SkillM2 NSURLComponents(各コンポーネントが対応するでエンコードされた各コンポーネントを使用するNSCharacterSet)が正しい方法だと思います。
Antonio Favata

2
URL文字列全体をエンコードしようとすることは絶対に避けてください。予期しないバグを引き起こし、場合によってはセキュリティホールを引き起こす可能性があります。URLをエンコードするための唯一の保証された正しい方法は、一度に1つずつ行うことです。
dgatwood 2016年

すごい。どうもありがとう、仲間!
フェリペ

100

Objective-Cの場合:

NSString *str = ...; // some URL
NSCharacterSet *set = [NSCharacterSet URLHostAllowedCharacterSet]; 
NSString *result = [str stringByAddingPercentEncodingWithAllowedCharacters:set];

NSUTF8StringEncodingのセットはどこにありますか?

パーセントエンコーディングを可能にする6つのURLコンポーネントとサブコンポーネントには、事前定義された文字セットがあります。これらの文字セットはに渡され -stringByAddingPercentEncodingWithAllowedCharacters:ます。

 // Predefined character sets for the six URL components and subcomponents which allow percent encoding. These character sets are passed to -stringByAddingPercentEncodingWithAllowedCharacters:.
@interface NSCharacterSet (NSURLUtilities)
+ (NSCharacterSet *)URLUserAllowedCharacterSet;
+ (NSCharacterSet *)URLPasswordAllowedCharacterSet;
+ (NSCharacterSet *)URLHostAllowedCharacterSet;
+ (NSCharacterSet *)URLPathAllowedCharacterSet;
+ (NSCharacterSet *)URLQueryAllowedCharacterSet;
+ (NSCharacterSet *)URLFragmentAllowedCharacterSet;
@end

非推奨のメッセージは次のように述べています(鉱山を強調):

代わりにstringByAddingPercentEncodingWithAllowedCharacters(_ :)を使用しますこれは、推奨されるUTF-8エンコーディングを常に使用し、特定のURLコンポーネントまたはサブコンポーネントをエンコードします。各URLコンポーネントまたはサブコンポーネントには、有効な文字に関する異なるルールがあるためです。

したがってNSCharacterSet、引数として適切なものを指定するだけで済みます。幸い、URLにはURLHostAllowedCharacterSet、次のように使用できる非常に便利なクラスメソッドがあります。

NSCharacterSet *set = [NSCharacterSet URLHostAllowedCharacterSet]; 

ただし、次のことに注意してください。

このメソッドは、URL文字列全体ではなく、URLコンポーネントまたはサブコンポーネント文字列をパーセントエンコードすることを目的としています。


4
アップルが人生を楽にしてくれるのが大好きです。ありがとうりんご。
ダック

5
「この方法は、URLストリング全体ではなく、URLコンポーネントまたはサブコンポーネントストリングをパーセントエンコードすることを目的としています。」の意味は何ですか。?
GeneCode

4
URLHostAllowedCharacterSetが「サポートされていないURL」というエラーを表示していたので、URLFragmentAllowedCharacterSetとその正常な動作を使用しました。
anoop4real 2016

1
これは+では機能せず、エンコードせず、仕様に従ってサーバー側のスペースに置き換えられます。
Torge

45

URLHostAllowedCharacterSetされて動作していない私のために。URLFragmentAllowedCharacterSet代わりに使用します。

目的-C

NSCharacterSet *set = [NSCharacterSet URLFragmentAllowedCharacterSet];
NSString * encodedString = [@"url string" stringByAddingPercentEncodingWithAllowedCharacters:set];

スイフト-4

"url string".addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)

以下は便利な(反転した)文字セットです。

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

ありがとうございました
Arpit B Parekh 2017

これらのセットのどれも含まれていないことに気付く価値があります+。そのため、サーバー側ではスペース ``として扱われ、クエリパラメータで渡された場合、文字列内のプラス記号はめちゃくちゃになります。
Asmo Soinio

21

Objective-C

このコードは私のために働きます:

urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];

4

Swift 2.2:

extension String {
 func encodeUTF8() -> String? {
//If I can create an NSURL out of the string nothing is wrong with it
if let _ = NSURL(string: self) {

    return self
}

//Get the last component from the string this will return subSequence
let optionalLastComponent = self.characters.split { $0 == "/" }.last


if let lastComponent = optionalLastComponent {

    //Get the string from the sub sequence by mapping the characters to [String] then reduce the array to String
    let lastComponentAsString = lastComponent.map { String($0) }.reduce("", combine: +)


    //Get the range of the last component
    if let rangeOfLastComponent = self.rangeOfString(lastComponentAsString) {
        //Get the string without its last component
        let stringWithoutLastComponent = self.substringToIndex(rangeOfLastComponent.startIndex)


        //Encode the last component
        if let lastComponentEncoded = lastComponentAsString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.alphanumericCharacterSet()) {


        //Finally append the original string (without its last component) to the encoded part (encoded last component)
        let encodedString = stringWithoutLastComponent + lastComponentEncoded

            //Return the string (original string/encoded string)
            return encodedString
        }
    }
}

return nil;
}
}

2

Swift 3.0の場合

urlHostAllowedcharacterSet を使用できます。

///ホストURLサブコンポーネントで許可されている文字の文字セットを返します。

public static var urlHostAllowed: CharacterSet { get }

WebserviceCalls.getParamValueStringForURLFromDictionary(settingsDict as! Dictionary<String, AnyObject>).addingPercentEncoding(withAllowedCharacters: CharacterSet.urlHostAllowed)

1

「このメソッドは、URLストリング全体ではなく、URLコンポーネントまたはサブコンポーネントストリングをパーセントエンコードすることを目的としています。」の意味は何ですか。?– GeneCode Sep 1 '16 at 8:30

これはhttps://xpto.example.com/path/subpath、URLのをエンコードするのではなく、の後に続くものだけをエンコードすることを意味します?

次のような場合に使用するユースケースがあるため、

https://example.com?redirectme=xxxxx

xxxxx完全にエンコードされたURLはどこにありますか。


0

受け入れられた回答に追加します。このメモを考慮に入れて

このメソッドは、URL文字列全体ではなく、URLコンポーネントまたはサブコンポーネント文字列をパーセントエンコードすることを目的としています。

URL全体をエンコードしないでください。

let param = "=color:green|\(latitude),\(longitude)&\("zoom=13&size=\(width)x\(height)")&sensor=true&key=\(staticMapKey)".addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) 
let url = "https://maps.google.com/maps/api/staticmap?markers" + param!
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.