【Swift】UITextViewのリンクをタップするとクラッシュした話

UITextView のリンクをタップ → アプリ内で画面遷移 ってのを実装したのですが、その際にリンクをタップしたらクラッシュしたことがありました。
大したエラーログも出ず、メインスレッドで呼ぶんじゃねぇの一点張り。
解決方法は単純でしたが、直接的な検索結果には出てこなかったので、残そうと思います (・ω・)

開発環境(前提条件)

・Xcode13.3
・Swift5
リンクは NSMutableAttributedString で追加している

クラッシュの内容

UITextView のリンクをタップすると、以下のようなログが出て怒られます。

This method should not be called on the main thread as it may lead to UI unresponsiveness.

「このメソッドをメインスレッドで呼び出すと UI が反応しなくなる可能性がありまっせ」言われてます。
UITextView に対してメインスレッドで呼ぶようなコード書いたかな…と思って調べたのですが、もちろんそんなことしてなくて、マジなんなん状態で1時間ほど無駄にしました。

クラッシュの原因

NSMutableAttributedString で追加したリンクに日本語が入っていたことが原因でした。笑
リンクをローカライズで変えていたので、ぱっと見で気付かず…マジしょぼんです (-ω-)
下記のようにリンクに日本語が入っていると URL が nil になってしまいます。

厳密に言うと、日本語が入っているというより、URLとして認識されない文字が正しいですね。
この URL を利用して UITextView にリンクが作られたために、クラッシュが起きていました。

解決方法

文字列にパーセントエンコーディングをかけることでクラッシュしなくなります。

この addingPercentEncoding(withAllowedCharacters:) を使うことで、URL で扱うことが出来ない文字をパーセント(%)と英数字で表現できるようになり、日本語が含まれているリンクでも URL で扱うことが出来ます。
ちなみにデコード処理は以下になります。

以上ォ!!

さいごに

クラッシュ内容は This method should not be called on the main thread as it may lead to UI unresponsiveness. じゃなくて、URL の変換に失敗しました的なことを出してほしい _:(´ཀ`」 ∠):_

Swift
スポンサーリンク
なんくるないさーエンジニア

コメント