LoginSignup
39

More than 5 years have passed since last update.

iOS 9 時代のURLエンコーディング(日本語環境)

Posted at

背景

iOS7からURLエンコーディング用にNSStringに stringByAddingPercentEncodingWithAllowedCharacters() が追加されました。
しかし、日本語のようなマルチバイトの言語ではエンコード対象の文字数が一定数を超えるとクラッシュする問題があり、安心して使うことができません。

参考
- 日本語文字列のURLエンコード時に潜む罠(iOS7 以上)
- Alamofire - escape function crashes when escaping long Chinese strings

代替手段として、これまではCore FoundationのCFURLCreateStringByAddingPercentEscapes()を使っておりましたが、iOS 9からなんとdeprecatedになってしまいます。(参考: CFURL Reference - Prerelease)

iOS9時代からの対処法

クラッシュ覚悟でNSString.stringByAddingPercentEncodingWithAllowedCharacters()を使うことができる人は少ないと思いますので、代替手段として使えるライブラリを作ってみました。

PercentEncoder
Lightweight library to escape string using so called URL encoding in Swift.
https://github.com/tasanobu/PercentEncoder

このライブラリではJavascriptCoreを使い、javascriptに用意されているURLエンコード用の関数 (encodeURI / encodeURIComponent / decodeURIComponent / decodeURIComponent) を呼ぶようにしています。
内部実装はこちらを見て頂くと分かります。

使い方

URLエンコーディングの機能は String,NSStringのextensionメソッドとPercentEncodingというenumで提供しています。
使い方は非常にシンプルです。

String extension
String
/// encodeURI
"http://tasanobu.jp?city=東京&year='20".ped_encodeURI()

/// decodeURI
"http://tasanobu.jp?city=%E6%9D%B1%E4%BA%AC&year='20".ped_decodeURI()


/// encodeURIComponent
let encoded = "東京".ped_encodeURIComponent()
// encoded to "%E6%9D%B1%E4%BA%AC"

/// decodeURIComponent
encoded.ped_decodedURIComponent()
// decoded back to "東京"
PercentEncoding enum

PercentEncoding にはjavascriptのURLエンコーディング用メソッドに対応した4つの値(encodeURI / encodeURIComponent / decodeURIComponent / decodeURIComponent)があり、使い方は次の通りです。

PercentEncoding
let url = "http://tasanobu.jp?city=東京&year='20"

/// EncodeURI
let escaped = PercentEncoding.EncodeURI.evaluate(string: url)
// encoded to "http://tasanobu.jp?city=%E6%9D%B1%E4%BA%AC&year='20"

/// DecodeURI
PercentEncoding.DecodeURIComponent.evaluate(string: escaped)
// decoded back to "http://tasanobu.jp?city=東京&year='20"


let value = "東京" // 東京 means Tokyo which is the capital of Japan.

/// EncodeURI
let encoded = PercentEncoding.EncodeURIComponent.evaluate(string: value)
// encoded to "%E6%9D%B1%E4%BA%AC"

/// DecodeURI
PercentEncoding.DecodeURIComponent.evaluate(string: encoded)
// decoded back to "東京"

システム要件

  • iOS 7.0+ (iOS 8.0+ when installing with Cocoapods)
  • Xcode 6.4

インストール方法

  • Cocoapods
 platform :ios, '8.0'
 use_frameworks!
 pod 'PercentEncoder'
  • git submodule

まとめ

使い方はシンプルで導入コストもそんなにないので、PercentEncoderを試して頂けると幸いです。
何か不明な点や不具合などありましたら、お気軽にこの記事にコメントして頂いたりやGithub上でIssueを作って頂ければと思います。

PercentEncoder
Lightweight library to escape string using so called URL encoding in Swift.
https://github.com/tasanobu/PercentEncoder

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
39