概要
iOS9・WatchOS2からCFURLCreateStringByAddingPercentEscapes
はdeprecatedになってしまいました。。。
iOS7から使えるstringByAddingPercentEncodingWithAllowedCharacters
を使ってパーセントエンコーディングしたほうがよさそうです
対応方法
For Swift
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
+ ( 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で非予約語として定義されているためエスケープされていなくて正解です
参考資料
-
NSCharacterSet Class Reference
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSCharacterSet_Class/#//apple_ref/occ/clm/NSCharacterSet -
RFC 3986 Internet Engineering Task Force
https://www.ietf.org/rfc/rfc3986.txt- https://www.ietf.org/rfc/rfc3986.txt