UITextView のリンクをタップ → アプリ内で画面遷移 ってのを実装したのですが、その際にリンクをタップしたらクラッシュしたことがありました。
大したエラーログも出ず、メインスレッドで呼ぶんじゃねぇの一点張り。
解決方法は単純でしたが、直接的な検索結果には出てこなかったので、残そうと思います (・ω・)
開発環境(前提条件)
・Xcode13.3
・Swift5
・リンクは NSMutableAttributedString で追加している
クラッシュの内容
UITextView のリンクをタップすると、以下のようなログが出て怒られます。
「このメソッドをメインスレッドで呼び出すと UI が反応しなくなる可能性がありまっせ」言われてます。
UITextView に対してメインスレッドで呼ぶようなコード書いたかな…と思って調べたのですが、もちろんそんなことしてなくて、マジなんなん状態で1時間ほど無駄にしました。
クラッシュの原因
NSMutableAttributedString で追加したリンクに日本語が入っていたことが原因でした。笑
リンクをローカライズで変えていたので、ぱっと見で気付かず…マジしょぼんです (-ω-)
下記のようにリンクに日本語が入っていると URL が nil になってしまいます。
1 2 3 4 5 |
let urlString = "https://google.com/search?q=日本語やん" let url = URL(string: urlString) // nil // 少々脱線しますが、urlString がリンクである必要はなく、 // "日本語やん" だと nil になりますが "japanese" だと大丈夫です。 |
厳密に言うと、日本語が入っているというより、URLとして認識されない文字が正しいですね。
この URL を利用して UITextView にリンクが作られたために、クラッシュが起きていました。
解決方法
文字列にパーセントエンコーディングをかけることでクラッシュしなくなります。
1 2 |
let urlString = "https://google.com/search?q=日本語やん" let url = URL(string: urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)) |
この addingPercentEncoding(withAllowedCharacters:) を使うことで、URL で扱うことが出来ない文字をパーセント(%)と英数字で表現できるようになり、日本語が含まれているリンクでも URL で扱うことが出来ます。
ちなみにデコード処理は以下になります。
1 2 3 4 5 6 7 8 9 |
let urlString = "https://google.com/search?q=日本語やん" let url = URL(string: urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)) // この時点での url.absoluteString の中身は // https://google.com/search?q=%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%82%84%E3%82%93 let decodeUrlString = url.absoluteString.removingPercentEncoding // decodeUrlString の中身は https://google.com/search?q=日本語やん |
以上ォ!!
さいごに
クラッシュ内容は This method should not be called on the main thread as it may lead to UI unresponsiveness. じゃなくて、URL の変換に失敗しました的なことを出してほしい _:(´ཀ`」 ∠):_
コメント