yashigani?.days

週刊少年ジャンプについてだらだら書きます

古来よりobjcプログラマはstringByAddingPercentEscapesUsingEncoding:がウソもんやということに悩まされてきたけど,普通にJSのencodeURI()使えばよかったんちゃうんかということに気づいた

モバイルアプリにWebとの連携は不可欠なわけで,iOSエンジニアがWeb APIを使うとき最初にどないすんねん!とぶつかる問題がパーセントエンコーディングだと思う. 我らがNSStringにはそれを解決するためのstringByAddingPercentEscapesUsingEncoding:という凄まじく長くてステキなメソッドがある. そして全てのiOSエンジニアは喜び勇んでこのメソッドを使い,絶望する.

なにを隠そうこのstringByAddingPercentEscapesUsingEncoding:ってのは,エスケープ対象の文字が少なく,本来エスケープされるべき文字をエスケープしてくれない. そんなこんなでCFURLCreateStringByAddingPercentEscapesなんか使っちゃったりしてCore Foundationデビューなんかしちゃったりするのである. (ちなみにアンエスケープはちゃんと動く.)

しかし,よくよく考えてみれば,JavaScriptならecodeURIがあって,こんなの問題にもならない. ここで,みんな大好きUIWebViewの登場である. UIWebViewにはみんなが愛してやまないstringByEvaluatingJavaScriptFromString:メソッドがある. NSURLのカテゴリにでも以下のように書いてやればパーセントエンコーディング問題は解決するのである. (どうでもいいけどloadURLWithStringとswizzleすると悪魔的だけどオサレ)

+ (instancetype)URLWithUnescapedString:(NSString *)URLString
{
    NSString *escaped = [[UIWebView new] stringByEvaluatingJavaSctiptFromString:[NSString stringWithFormat:@"encodeURI(\"%@\");", URLString];
    return [self URLWithString:escaped];
}

こんなためにいちいちUIWebView作るのはたいそうすぎるとか思うかもしれないけど,それはstaticにするなりで少々マシにすることはできると思うし,なによりiOS 7以降ならJSContextもある. 結局なにが言いたいかというと,JavaScriptの資産使うためにUIWebView使ったり,JSContext使うの結構アリだと思うということ.

関連