LoginSignup
13
10

More than 5 years have passed since last update.

iOS7以上におけるクエリストリングに対するパーセントエンコーディング

Last updated at Posted at 2015-09-27

概要

iOS9・WatchOS2からCFURLCreateStringByAddingPercentEscapesはdeprecatedになってしまいました。。。
iOS7から使えるstringByAddingPercentEncodingWithAllowedCharactersを使ってパーセントエンコーディングしたほうがよさそうです :smile:

対応方法

For Swift

code
static func escapeURLString(URLString: String) -> String {
    //Reserved characters defined by RFC 3986
    let genDelims = ":/?#[]@"
    let subDelims = "!$&'()*+,;="
    let reservedCharacters = genDelims + subDelims
    //URLQueryAllowedCharacterSetからRFC 3986で予約されている文字を除いたもののみエスケープしない
    let allowedCharacterSet = NSCharacterSet.URLQueryAllowedCharacterSet().mutableCopy() as! NSMutableCharacterSet
    allowedCharacterSet.removeCharactersInString(reservedCharacters)
    return URLString.stringByAddingPercentEncodingWithAllowedCharacters(allowedCharacterSet) ?? string
}

For Objective-C

code
+ ( NSString * _Nonnull )escapeWithURLWithString:( NSString * _Nonnull )URLString
{
    //Reserved characters defined by RFC 3986
    NSString *genDelims = @":/?#[]@";
    NSString *subDelims = @"!$&'()*+,;=";
    NSString *reservedCharacters = [NSString stringWithFormat:@"%@%@",
                                    genDelims,
                                    subDelims];
    //URLQueryAllowedCharacterSetからRFC 3986で予約されている文字を除いたもののみエスケープしない
    NSMutableCharacterSet * allowedCharacterSet = [NSCharacterSet URLQueryAllowedCharacterSet].mutableCopy;
    [allowedCharacterSet removeCharactersInString:reservedCharacters];
    return [URLString stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet] ? : URLString;

}

NSCharacterSetがもつURLQueryAllowedCharacterSetはAppleのドキュメントによると、

Returns the character set for characters allowed in a query URL component.
The query component of a URL is the component immediately following a question mark (?). For example, in the URL http://www.example.com/index.php?key1=value1#jumpLink, the query component is key1=value1.

とあり、この許可されている文字からRFC 3986で定義されているgenDelims、subDelims(合わせたものが予約文字)を除外したものが、エスケープしなくてよい文字になります。

実行例

試しに、:/?#[]@!$&'()*+,;=あ-_~. に対してエスケープをかけたところ
%3A%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D%E3%81%82-_~.と出力されることを確認しました。
-_~.はRFC 3986で非予約語として定義されているためエスケープされていなくて正解です :thumbsup:

参考資料

13
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
10