[Swift3.0] 日本語を含むURLをNSURLにする方法と注意点

By | 2016年9月29日

日本語を含むURL文字列(String型)をNSURLに変換しようとすると、無効なURLと判断され nil が返されます。

そこで、関数 stringByAddingPercentEncodingWithAllowedCharacters を使って日本語をエンコードします。

Swift3.0(iOS10)以降は stringByAddingPercentEncodingWithAllowedCharacters が削除され、代わりに addingPercentEncoding(withAllowedCharacters:) になりました。

その他にも、Swift3.0では stringBy〜 というメソッドは削除され、名前が変更されています。

一例を挙げると、以下のようなメソッドが変更対象となっています。

iOS10でのメソッド名の変更

Foundation Changes for Swift

例えば、addingPercentEncoding を使って、

https://joyplot.com/documents/日本語を含むURLをNSURLにする/

というURLをエンコードすると以下のように変換されます。

https://joyplot.com/documents/%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%82%92%E5%90%AB%E3%82%80URL%E3%82%92NSURL%E3%81%AB%E3%81%99%E3%82%8B/

実際にNSURLに変換するコードを以下に示します。

            let targetURL = "https://joyplot.com/documents/日本語を含むURLをNSURLにする/"
            let encodedURL = targetURL.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)
            
            guard let url = NSURL(string: encodedURL!) else {
                print("無効なURL")
                return
            }
            
            print(url)

もし NSURLのコンストラクタにエンコード前のURL(targetURL)を渡した場合は nil が帰ってくるため「無効なURL」と出力されます。

addingPercentEncoding に関する補足

この関数の引数には、エンコード後のURLに含ませることを許可する文字セットを渡します。

上の例で指定している NSCharacterSet.urlQueryAllowed はURLのクエリ内で使用可能な文字(記号)を返します。日本語を含むURLを扱えるようにする目的であれば、これで問題なく動作します。

しかし、記号をエスケープする場合、ここで指定した内容によって結果が大きく変わるので注意が必要です。

例えば、以下のように引数を変えて記号をエンコードしてみます。

        print("!*'();:@&=+$,/?%#[]-._~ ".addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)!)

        print("!*'();:@&=+$,/?%#[]-._~ ".addingPercentEncoding(withAllowedCharacters: NSCharacterSet.alphanumerics)!)

出力には以下のような違いが出ます。

NSCharacterSet.urlQueryAllowed を指定した場合(上)

!*'();:@&=+$,/?%25%23%5B%5D-._~%20

NSCharacterSet.alphanumerics を指定した場合(下)

%21%2A%27%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%25%23%5B%5D%2D%2E%5F%7E%20

このように、適切な記号をエスケープして日本語や記号を含むURLを処理する必要があります。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です