概要
- Web側からオリジナルアプリ(スキーマ)がインストールされているか判定し、その判定結果によって処理を分岐させる。
前提
-
myapp://
というオリジナルスキーマからアプリが起動できること - スマホからのアクセスのみ対象。PC からのアクセスはアプリ紹介ページに遷移させる。
- アプリ未インストールの場合、各 OS(iOS、Android) のオリジナルアプリのマーケットに遷移させる
- アプリインストール済みの場合、アプリを起動する
目的
Web 側からオリジナルアプリがインストールされているか判定する。
アプリ非対応デバイス
- アプリ紹介ページに遷移
アプリ対応デバイスである
- インストール済み
- アプリを起動
- 未インストール
- アクセスしている OS に沿ったアプリのマーケットに遷移
問題点
iOS と Android では標準ブラウザで特定のスキーマに対する遷移方法が異なる
iOS
- 認識できないスキーマには遷移前にアラートが表示される
- スクリプト実行元ページにとどまる
Android
- 認識できないスキーマに遷移後、エラーページが表示される
- スクリプト実行元ページから離脱
sample.js
var checkedAt = (new Date()).getTime();
window.setTimeout(function() {
var lagtime = (new Date()).getTime() - checkedAt;
if (lagtime > LAG_TIME) {
window.location = useragent ? IOS_STORE_URL : ANDROID_STORE_URL;
return;
}
}, TIMEOUT);
window.location = MY_APP_SCHEMA;
- 上記の問題として、Android の場合スクリプト実行元から離脱したタイミングで残りのスクリプトが止まる
-
setTimeout()
が実行されない- 常にアプリインストール済みの挙動になる
-
解決方法
- iframe(魔法のランプ)を使いスクリプト実行元のページから離脱しないようにする
- スクリプト実行元のページ内部で擬似的にスキーマ遷移させる
useragent を判定
useragent.js
window.MY_APP = window.MY_APP || {};
MY_APP.UserAgent = (function() {
var ua = navigator.userAgent;
if ((ua.indexOf('Android') > 0 && ua.indexOf('Mobile') == -1)) {
return 0;
} else if ((ua.indexOf('Android') > 0 && ua.indexOf('Mobile') > 0)) {
return 0;
} else if (ua.indexOf('iPhone') > 0) {
return 1;
} else if (ua.indexOf('iPad') > 0) {
return 1;
} else if (ua.indexOf('iPod') > 0) {
return 1;
} else {
return -1;
}
});
認識可能スキーマか判定
index.html
<!DOCTYPE html>
<html>
<head>
<title>MY APP</title>
<script type="text/javascript" src="js/jquery-1.9.0.min.js"></script>
<script type="text/javascript" src="js/useragent.js"></script>
</head>
<body>
<script>
const IOS_STORE_URL = "https://itunes.apple.com/jp/app/hoge/";
const ANDROID_STORE_URL = "https://play.google.com/store/apps/details?id=hoge";
const MY_WEB_PAGE_URL = "https://example.com";
const MY_APP_SCHEMA = "myapp://";
const USER_AGENT_NOT_SMART_PHONE = -1
const LAG_TIME = 400;
const TIMEOUT = 1000;
$(function() {
if (MY_APP.UserAgent() === USER_AGENT_NOT_SMART_PHONE) {
window.location = MY_WEB_PAGE_URL;
return false;
}
$("body").append("<iframe src='" + MY_APP_SCHEMA + "' style='display:none'/>");
var checkedAt = (new Date()).getTime();
window.setTimeout(function() {
var lagtime = (new Date()).getTime() - checkedAt;
$("iframe").remove();
if (lagtime > LAG_TIME) {
window.location = useragent ? IOS_STORE_URL : ANDROID_STORE_URL;
return;
}
}, TIMEOUT);
});
</script>
</body>
</html>