Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
41
Help us understand the problem. What are the problem?
@toto_kit

【iOS14】デフォルトブラウザを変更した時にcanOpenURLがfalseになる問題

何が起こっている?

iOS14 PublicBeta8以降を入れたiOS端末で、デフォルトブラウザを変更した際にブラウザ遷移が行えない。

発生条件

  • iOS14PB版、もしくはGM版、正式版(iOS14.0)
    • 2020/09/28追記:iOS14.0.1でも発生することを確認済み
  • デフォルトブラウザをsafari以外に設定していること

デフォルトブラウザ設定方法

  1. 「設定」アプリ起動
  2. デフォルトブラウザにしたいアプリへ移動(例:Chrome,Microsoft Edge)
  3. 「デフォルトブラウザApp」を開く
  4. 標準ブラウザを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のアプリの動作を保証する解決方法ではございません

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
41
Help us understand the problem. What are the problem?