anz blog

URLComponentsでmailtoリンクを生成してメール送信画面を起動させた場合の挙動が変わっていた話

なんとなくアプリのお問い合わせからのメール起動部分をみていて、表示がおかしくなっているのに気づいたのでそこらの調査と対応をした話です。

問題

アプリのお問い合わせからメール送信画面を起動してお問い合わせをしてもらうというのは、割とありがちな方法だとは思いますが、今回そこをみていて違和感を覚えました。
こんな感じです。

違和感を覚える送信画面

具体的には以下の2つです

  • 宛先のメールアドレスが // で始まっている
  • 本文部分に <BR> と表示されている

メールアドレスは表示がバグっているだけで実際には送信できたりするのだろうか?とも思ったのですが、送信エラーになるので普通にスラッシュで扱われているようでした。
本文部分は見苦しいだけですが、メールが送信できないというのはなかなか致命的な感じがします。

実装部分

実装は URLComponents を利用して mailto の URL を生成してそれで開いているという感じです。

var components = URLComponents()
components.scheme = "mailto"
components.host = "[email protected]"
components.queryItems = [
    URLQueryItem(name: "subject", value: "件名"),
    URLQueryItem(name: "body", value: "1行目\n2行目\n3行目")
]
guard let url = components.url else {
    return
}
UIApplication.shared.open(url, options: [:], completionHandler: nil)

原因調査

以前まで問題なく動いていたはずなのにいつからかできなくなっていたので、iOSのバグかな?と思いググってみて行き当たった記事がありました。

Mailto url encoding issue iOS 14.6 | Apple Developer Forums

これは問題部分で上げた後者のほう <BR> で表示されるというものスレッドでした。
どうやら iOS 14.6 から改行が br タグで表示されてしまう様になっていたようです。(全然気づかなかった…)
ただ、iOS 15.0.1 の iPhone だとちゃんと改行されて表示されるので、iOS 15 以降では改善されているかもしれません。

前者の方は特に何かのページが引っかかったというわけではないのですが、
頭にスラッシュが2つついているというのと、mailtoでググると maito:[email protected] というので紹介されているので、URLComponents で生成される URL は mailto://[email protected] となっていることが原因なのかな?と当たりをつけてみました。
そこで URL(string: "mailto:[email protected]") と URL を生成して渡してみたら、宛先メールアドレスはちゃんとセットされるようになりました。
どうやら、:// の解釈が変わったようです。いつからかはわからないですが、URL エンコードの扱いが変わったという意味では br タグと同じなので、同じく iOS 14.6+ で発生するようになったのかもしれないです

解決策

mailto で送信画面を開くのではなくて、MFMailComposeViewController を使ってアプリ内で送信画面を開きましょうというだけです。
実装事態は難しいことは全然ないですし、ドキュメントもちゃんと用意されているので割愛します。

懸念点

アプリ内で送信画面を開けてユーザ体験も良くなるし、良いことだらけのような気もしますが1つだけデメリット(?)があります。
デフォルトのメールアプリを標準メールアプリ以外(例えば Gmail アプリなど)にしていても、MFMailComposeViewController で呼ばれる送信画面は、標準メールアプリのものになります。
ので、Gmail アプリだけセットアップしていて標準メールアプリはセットアップすらしていないというユーザーの場合は、逆に使い勝手がわるい挙動になってしまいます。

これを許容できるかどうかで対策方法は変わってきそうですね…

参考