何が起こっている?
iOS14 PublicBeta8以降を入れたiOS端末で、デフォルトブラウザを変更した際にブラウザ遷移が行えない。
発生条件
- iOS14PB版、もしくはGM版、正式版(iOS14.0)
- 2020/09/28追記:iOS14.0.1でも発生することを確認済み
- デフォルトブラウザをsafari以外に設定していること
デフォルトブラウザ設定方法
- 「設定」アプリ起動
- デフォルトブラウザにしたいアプリへ移動(例:Chrome,Microsoft Edge)
- 「デフォルトブラウザApp」を開く
- 標準ブラウザをSafariからChromeに変更する
原因
UIApplicationのcanOpenURL
メソッドがfalseを返却している。
これが、iOS14の仕様なのかバグなのかは現時点(日本時間2020/09/16)では不明。
canOpenURL returns false when I changed the default browser on iOS 14
そもそもcanOpenURLとは?
UIApplication | Apple Developer Documentationより
Determine whether there is an installed app registered to handle a URL scheme (canOpenURL(_:))
(URLスキームを処理するために登録されたインストール済みアプリがあるかどうかを判別する)
アプリから別のアプリを起動する(URLスキーム)際に、処理するためのアプリが端末に存在しているかを返す関数。
(そもそもここの認識が間違えていて、「全てのURL起動にcanOpenURLを通す」という誤用?が今回の事件を引き起こしたと思われる)
対応方法
その1:canOpenURLを通さない
そもそもiOS端末にはブラウザアプリとしてSafariが必ず入っている。
かつ長押ししてもsafariアプリは削除もできないので、
ブラウザ起動をしようとして、iOS端末にブラウザアプリがないことは有り得ない はず。
(とはいえ、ブラウザ起動でcanOpenURLがfalseを返すことはないはずが、今回起こっているわけですが)
2020/09/29追記:コメントにて、構成プロファイルのallowSafari
でSafariを無効化できると教えていただきました。設定している場合は注意してください。
上記の通り、canOpenURLの目的は別のアプリの起動ができるかを確認するためのもののため、
ブラウザ起動のためのURL起動の場合は、canOpenURLを通す必要はなさそう。
よっていきなりopen
を叩くように修正する。
これでデフォルトブラウザを変更していても、ちゃんとsafariではないブラウザアプリで起動される。
// AS-IS例
if UIApplication.shared.canOpenURL(URL(string: "https://qiita.com/")!) {
UIApplication.shared.open(URL(string: "https://qiita.com/")!)
} else {
print("ブラウザ起動失敗")
}
// To-BE例
UIApplication.shared.open(URL(string: "https://qiita.com/")!)
その2:plistにhttp/httpsを追加する
Preparing Your App to be the Default Browser or Email Client | Apple Developer Documentationより
Fulfilling Default Browser Requirements
Apps that register as a default web browser option must satisfy the following criteria:
Your app must specify the HTTP and HTTPS schemes in its Info.plist file.
(デフォルトのブラウザ要件を満たす
デフォルトのWebブラウザオプションとして登録するアプリは、次の条件を満たす必要があります。
アプリは、Info.plistファイルでHTTPおよびHTTPSスキームを指定する必要があります。)
ブラウザ起動のURLを許可するようplistを以下のように変更する。
<key>LSApplicationQueriesSchemes</key>
<array>
<string>http</string>
<string>https</string>
</array>
2020/9/28追記:デフォルトのメールアプリを変更した場合、 mailto:// も同様にcanOpenURLがfalseになりますが、同じくplistに追加で回避可能です。
参考
公式:
UIApplication | Apple Developer Documentation
canOpenURL(_:) | Apple Developer Documentation
参考:
特定のアプリがインストール済みかチェックする
[iOS] ディープリンク(Custom URL Scheme)でアプリを起動する
iOS9でカスタムURLスキームの遷移に失敗するときの注意点
間違っている点や他の方法があれば教えてください!
iOS14の発表でバタバタしている同志のiOSエンジニアのみなさま、お互いに本当にお疲れ様です。
免責:全てのiOS14のアプリの動作を保証する解決方法ではございません