iOS
Safari

iOSアプリ未インストール時にSafariでカスタムURLスキームを開く時の対策

More than 5 years have passed since last update.

iOSアプリケーションにカスタムURLスキームを実装し、SafariからそのURLを開く際にまだユーザがそのアプリケーションをインストールしていなければそのURLを開けずにページエラーになってしまう。その場合はアプリケーションをインストールする導線を張りたい。


対策1

workaroundとして以下のhackがある。

setTimeout(function() {

window.location = "http://itunes.com/apps/yourappname";
}, 25);
window.location = "custom-uri://";


hack1の説明

window.locationにてカスタムURLスキームを設定し、そのURLに対応したアプリケーションがない場合(Safari自身も対応していない場合)、window.location = "custom-uri://" の処理で画面遷移はせず、Safariは現在のページにとどまるためsetTimeoutがすぐ処理され、window.location = "http://itunes.com/apps/yourappname" によりStoreへ飛ばすコードが実行される。

これによりアプリがインストールしていない場合にStoreに飛ばすということが実現できる。


hack2の説明

SafariはURL ( custom-uri:// ) を開くアプリケーションが見つからない場合にAlertを表示する。

Alertを表示後にさらに別のアプリケーション(上記の例ではApp Storeアプリが http://itunes.com/apps/yourappname をハンドリング)で開けるカスタムURLスキームを開くと、SafariがAlertを消す動きを見せるため、25msのような短い間隔であればユーザにAlertを見せないように振る舞うことができる。

逆にsetTimeoutで開くページがSafariで扱えるウェブページの場合Alertはキャンセルされず残ったままになるようだった。そのためApp Storeの前に自前のヘルプページを挟みたいという要件があるとsetTimeoutの間隔を短くするこのhackは使えずにAlertが残ったままになる。


対策1の問題点

カスタムURLスキーム ( custom-uri:// ) を実装したアプリケーションがインストール済みの場合のフローが問題になる。

インストール済みならURL ( custom-uri:// ) をそのアプリケーションがフォラグランドになって処理を行うが、setTimeoutの処理はキャンセルされないので、ユーザがSafariに戻ったときにインストール済みにもかかわらず毎回 window.location = "http://itunes.com/apps/yourappname"; が実行されストアのページが開れてしまうという問題が起きる。


対策2

対策1の問題点を回避するworkaroundとして時刻をチェックするというhackがある。

var checkedAt = new Date();

setTimeout(function() {
var t = new Date() - checkedAt;
if (t < 2000) {
window.location = "http://itunes.com/apps/yourappname";
}
}, 1000);
window.location = "custom-uri://";


hack3の説明

アプリケーションがURLを開いてフォラグランドになれば当然Safariがバックグランドに回るためSafariの実行が停止し、すぐにはsetTimeoutの処理は実行されない。

Safariに戻ったあとにこのsetTimeoutが実行されるがこの時には時間が経っているのでsetTimeout内で時刻をチェックすれば、インストール済みのフローではApp StoreのURLを開かないようにできる。

iPhone 4Sで試したところ500msくらいであればSafariがバックグランドに入る前にsetTimeoutが実行されてしまったので、1000msにしてみたがこの辺りはタイミング次第なので調整が必要かもしれない。


対策2の問題点

対策1のhack2が使えないということになる。対策1のhack2ではアプリケーション未インストール時に表示されるAlertをsetTimeoutを25msにすることで即座にキャンセルしていたが、この対策を使うと1000msなのでその間1秒間ユーザにAlertを見せてしまうことになる。


まとめ

今のところこれ以外のworkaroundを知らないため全ての解決方法がわからない。対策1と対策2の問題を比較した場合、インストール前のフロー問題とインストール後のフローの問題のどちらに優先度を置くかによって判断が変わる。

個人的にはインストール前にちょっとAlertが表示されることよりも、インストール後に毎回ストアに遷移してしまうほうが問題だと感じているので対策2を選ぶのがよいと考えている。


参考にしたもの