iOSでschemaプロトコルを使ってAPPを呼び出したり、iframeを使ってAPPを開いたりする例
iOSでは、ブラウザでAPPを開く2つの方法を提供しています。Smart App Bannerとschemaプロトコルです。
Smart App Banner
一metaタグを通して、ラベルにapの情報を付けて、開いた後の行為、例えば、ap-indのようなコードの形をしています。
具体的には下開発の文書が見られます。今日はSmart APP Bannerは私達の主役ではありません。私達はschemaと言います。
schema URLを使ってiOSアプリを開きます。
schemaはカスタムurlプロトコルのように、カスタムプロトコルで自分のアプリケーションを開くことができます。
myapplink://
# facebook
fb://
# itunes
itms-apps://
#
sms://
もしappを開くなら、一番簡単なのはリンクを通して、例えば私達がhtmlにこう書きます。
<a href="myapplink://"> app</a>
ユーザーがリンクをクリックすると、対応するアプリを開くことができます。バインディングclickイベント
しかし、実際に私たちがもっと多いのはバインディングイベントです。例えば、弾の層を作るなど、ひたすらaタグを使うことはできません。ですから、二つの方法で解決できます。location.hrefとiframe。
iframeの方式は開発でよく使われていますが、彼にもいくつかの問題があります。
1.私たちはアプリを開いているかどうかを判断するための良い方法を持っていません。
2.historyの変化を引き起こす
3.historyの変化を引き起こすので、webviewに問題があります。例えば、調べてみます。ページを開けます。iframeがあれば、safariで開けます。実際に開けたのはiframeのページです。
4.もしページがAndroidシステムに漏れたら、ページが開けられないという問題もあります。
5.appがないと、調整がうまくいかなくなります。iosのsafariは自分でダイアログを開きます。URLなどのヒントがありません。
だから今の問題は、どのようにiframeがあるアプリを開いているかを知るか、すなわちiframeを解決してappを開きます。
iOSシステムでiframeを使ってapを開く
頭のいいあなたは考えたかもしれません。iframeのonload事件です。しかし、残念ながら無効です。そこで、タイマーが見つかりました。しばらくの間(例えば、500 ms)、ボタンをクリックしたら、ページが切断されていません。(アプリを調整したら、ページのプロセスが中断されます。)プロセスが中断され、タイマーが中断されます。この時、タイムマーカーが起動されないはずです。失敗したら、タイムマーカーがトリガされます。私達は一定の時間内にページが切られていないと判断しました。失敗したと思います。
また、timerがトリガした時のtimer 2によって、差をつけて、あまりにも逸脱しているかどうかを判断する(切った後の時間はtimer実際のタイミングの500 msより長いはず):
function openIos(url, callback) {
if (!url) {
return;
}
var node = document.createElement('iframe');
node.style.display = 'none';
var body = document.body;
var timer;
var clear = function(evt, isTimeout) {
(typeof callback==='function') && callback(isTimeout);
if (!node) {
return;
}
node.onload = null;
body.removeChild(node);
node = null;
};
var hide = function(e){
clearTimeout(timer);
clear(e, false);
};
node.onload = clear;
node.src = url;
body.appendChild(node);
var now = +new Date();
// , 1
timer = setTimeout(function(){
var newTime = +new Date();
if(now-newTime>600){
// ,
// timer , 500ms
// !
clear(null, false);
}else{
clear(null, true);
}
}, 500);
}
方法は確かに見えますが、現実はいつも残酷です。別のブラウザのapp(webviewを含む)は、自分のバックグラウンドに常駐時間があります。つまり、ブラウザが切断された後、バックグラウンドに10 s常駐していたら、タイマーを5 s有効期限が過ぎたら無駄です。そして、5 sのタイマーは、ユーザが5 s待ちます。相互作用もあなたにこのようにさせません。
最後に私達はPageshowとPagehideのイベントを思い付きました。つまり、ブラウザが開いているアプリに切られたら、ブラウザのPagehideイベントをトリガするはずです。
しかし、コードテストを通して、uc、chromeでは、pagehideとpageshowの方法は触発されません。safariでは可能です。
結論:
1.iframeを使ってschema URLを呼び出します。
2.タイマーを使って、しばらくの間に調整が成功したかどうかを判断する。
3.pageshowとPagehideを使ってタイマーを補助し、より詳細な判断をする。
4.タイマーの中にalertがあると飛び出さないかもしれないということに驚きました。後のdomは意外にも5.実行しましたが、alertはポップアップしていません。alertの実現に関係があるかもしれません。
6.実験で2つのタイマーを使ったのは、ブラウザを切ってから、時にはtimeoutがトリガして、pagehideとpageshowの前に。
7.timerの実際の実行時間差を計算するのも無理です。
最後に研究のコードを添付して、比較的に信頼できる方法です。まだある程度の失敗がありますが、(第三者ブラウザのPagehideとPageshowはトリガしません):
<p><button id="btn"> !alert, </button></p>
<p><button id="btn2"> !alert2, alert info,info , alert </button></p>
<p><button id="btninfo"> !info </button></p>
$(function(){
var $info = $('#info');
function info(msg){
var p = $('<p>'+msg+'</p>');
$info.append(p);
}
$('#btn').on('click', function(){
openIos('baiduboxapp://', function(t){
if(t){
alert('timeout or no baidu APP');
}else{
alert('invoke success');
}
});
});
$('#btn2').on('click', function(){
openIos('baiduboxapp://', function(t){
if(t){
info('timeout or no baidu APP2');
alert('timeout or no baidu APP2');
}else{
info('invoke success2');
alert('invoke success2');
}
});
});
$('#btninfo').on('click', function(){
openIos('baiduboxapp://', function(t){
if(t){
info('timeout or no baidu APP');
}else{
info('invoke success');
}
});
});
});
function openIos(url, callback) {
if (!url) {
return;
}
var node = document.createElement('iframe');
node.style.display = 'none';
var body = document.body;
var timer;
var clear = function(evt, isTimeout) {
(typeof callback==='function') && callback(isTimeout);
window.removeEventListener('pagehide', hide, true);
window.removeEventListener('pageshow', hide, true);
if (!node) {
return;
}
node.onload = null;
body.removeChild(node);
node = null;
};
var hide = function(e){
clearTimeout(timer);
clear(e, false);
};
window.addEventListener('pagehide', hide, true);
window.addEventListener('pageshow', hide, true);
node.onload = clear;
node.src = url;
body.appendChild(node);
var now = +new Date();
// , 1
timer = setTimeout(function(){
timer = setTimeout(function(){
var newTime = +new Date();
if(now-newTime>1300){
clear(null, false);
}else{
clear(null, true);
}
}, 1200);
}, 60);
}