【iOS9】特定のURLスキームのみを呼び出し可能にする→.canOpenURL(url)について

スポンサーリンク

URLスキームでの他アプリの呼び出し等についてもセキュリティ面で強化機能が追加されるようですね。

参考:「iOS9でカスタムURLスキームの遷移に失敗するときの注意点

iOS9からURLスキームの使用に関する変更があり、 従来のopenURLを実行するだけではカスタムURLスキームの遷移が使用できなくなりました。

これもアプリによっては影響がありそうということで、実際に確認してみました。(Xcode7 beta4時点)

「onetwopunch://」というURLスキームを呼び出せるように設定するには、Info.plistで「LSApplicationQueriesSchemes」をArray型で作成し、URLスキーム部分(「://」のない「onetwopunch」でいいみたい)をその配列に加えていく、ということです。カスタムスキームをここに設定することで特定のアプリだけを起動する、ということが可能になります。ここに指定がない場合やその対象となるアプリがインストールされていない場合は、.canOpenURL(url)がtrueを返しません。

「UIApplication.sharedApplication().openURL(url)」を実行する前に「UIApplication.sharedApplication().canOpenURL(url)」で許可されているかを判定できる、ということですかね。

01

呼び出しのためのボタンを配置して、そこに以下のように書いています。

許可していても、インストールされていないiOSシミュレータ環境で試すと、trueにならず呼び出せませんでした。これはつまり、「インストールされていない、呼び出せないということをアプリ側でしっかり認識できる」ということでもありますね。

02

許可していても、インストールされていないiOSシミュレータでは、

-canOpenURL: failed for URL: “onetwopunch://” – error: “(null)”

と出力されました。

では、OneTwoPunch (URLスキームは「onetwopunch://」)をiOS9がインストールされている実機にインストールして、その実機環境で試してみます。(ちなみに、そのURLスキームが本当に呼び出せるのかを確認するには、SafariのURL欄に「onetwopunch://」と入力してEnterを押します。そのアプリがインストールされていれば起動します。)

今度は、UIApplication.sharedApplication().canOpenURL(url)がtrueを返したので、.openURL(url)で起動させることができました。

03

アプリを起動する際に、以下のようなメッセージが出ます。

 04

そして起動したアプリのステータスバーには、前アプリに戻るためのボタンが表示されています。

 05

では、Info.plistで許可されていない場合はどうなるかを試してみます。(このテストをするには、一度Product>Cleanでビルドをクリアして試した方がよさそうです。)

canOpenURL: failed for URL: “onetwopunch://” – error: “This app is not allowed to query for scheme onetwopunch”

許可されていないURLスキームを呼び出したということが、このようなエラーメッセージで確認できました。

しかし!これちょっと勘違いしていたかもしれないのですが、そもそも「if (UIApplication.sharedApplication().canOpenURL(url)) {」の判定をいれずに直接「.openURL(url)」してみたところ、許可していないURLスキームを呼び出せたぞ??自分のアプリだからかな?

.canOpenURL(url)で判定することで意図していないURLスキームは呼び出さないようにできるようになった、ということですかね。WebView内からの良からぬURLスキーム呼び出しを受け取った場合でもcanOpenURLで判定すれば、抑制できる感じですかね。

UrlschemeViewController swift

有名な50ほどのURLスキームだともともと許可されているようなので、こちらのページにある見知らぬURLスキームでも試してみましたが、同様に判定なしであれば起動できました。。(Xcode 7 beta4時点)beta5でも試してみなきゃ。。

追記:こちら↓に非常に詳しい実験をしている記事がありました。

//gist-embed