HTML5啟動手機中的APP(IOS)
在iOS中,需要調起一個app可以使用schema協議,這是iOS原生支援的,並且因為iOS系統中都不能使用自己的瀏覽器核心,所以所有的瀏覽器都支援,這跟android生態不一樣,android是可以自己搞核心的,但是iOS不行。
在iOS中提供了兩種在瀏覽器中開啟APP的方法:Smart App Banner和schema協議。
Smart App Banner
即通過一個meta 標籤,在標籤上帶上app的資訊,和開啟後的行為,例如:app-id之類的,程式碼形如:
具體可以看下開發文件:https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html
今天Smart APP Banner不是我們的主角,我們說的是schema
使用schema URL來開啟iOS APP
schema類似自定義url協議,我們可以通過自定義的協議來開啟自己的應用,形如:
myapplink://
# 例如 facebook的
fb://
# itunes的
itms-apps://
# 還有簡訊也是類似的
sms://
如果要開啟一個app,最簡單的方式是通過一個連結,如我們在html中這樣寫:
<a href="myapplink://">開啟我的app</a>
當使用者點選連結的時候就可以開啟對應的app。
繫結click事件
但是實際中我們更多的情況是繫結事件,比如做個彈層啥的,不能一味的用a標籤啊,所以可以通過兩種方式來解決:location.href和iframe。
iframe的方式是開發中常用的,但是他也有一些問題:
1.我們沒很好的方式來判斷是否開啟了app
2.會引起history變化
3.因為引起history變化,所以一些webview會有問題,比如:我查查,開啟一個頁面,如果有iframe,選擇在safari中開啟,實際開啟的是iframe的頁面
4.如果頁面暴漏給了android系統,那麼也會出現頁面打不開,之類的問題
5.如果沒有app,調起不成功,ios的safari會自己彈出一個對話方塊:打不開網址之類的提示
所以現在的問題是:如何知道iframe已經開啟了某個app,即解決iframe開啟app回撥。
使用iframe在iOS系統中開啟app
聰明的你可能想到了,iframe的onload事件啊,可是遺憾的說,無效!所以我們找到了定時器(setTimeout),通過一個定時器,如果在一段時間內(比如500ms),當點選了按鈕(記錄time1),頁面沒有切走(調起app之後,頁面程式會被中斷),程式中斷,那麼計時器也會中斷,這時候應該不會觸發timer,如果調起失敗,那麼timer會就觸發,我們判斷下在一定時間內如果頁面沒有被切走,就認為調起失敗。
另外通過timer觸發時候的timer2,做差,判斷是否太離譜了(切走了之後的時間應該比timer實際定時的500ms要長):
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),都有自己在後臺的常駐時間,即:假如一個瀏覽器他在被切走之後,後臺常駐10s,那麼我們設定定時器5s過期就是徒勞的,而且5s的定時器,使用者要空等5s!互動也不讓你這樣幹啊!
最後我們想到了pageshow和pagehide事件,即如果瀏覽器被切走到了要開啟的app,應該會觸發瀏覽器的pagehide事件,而從app重新返回到瀏覽器,就會觸發pageshow方法。
但是經過程式碼測試發現,在uc、chrome中,不會觸發pagehide和pageshow的方法,而在safari中可以的。
結論:
1.使用iframe呼叫schema URL
2.使用定時器判斷在一段時間內是否調起成功
3.使用pageshow和pagehide來輔助定時器做更詳細的判斷
4.定時器中如果有alert可能不會被彈出,這一點很吃驚!後面的dom竟然5.執行了,但是alert沒彈出,可能跟alert的實現有關係吧
6.在實驗中我使用了兩個定時器,是因為切回瀏覽器之後,有時候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);
}
相關文章
- iOS App啟動過程iOSAPP
- iOS App 的完整啟動過程iOSAPP
- HTML5手機APP開發入(3)HTMLAPP
- HTML5手機APP開發入(4)HTMLAPP
- HTML5手機APP開發入(5)HTMLAPP
- Twitter iOS App 啟動動畫的實現iOSAPP動畫
- 分分鐘解決iOS開發中App啟動廣告的功能iOSAPP
- iOS 手機振動棒iOS
- ios 手機app效能監控工具iOSAPP
- HTML5手機APP開發入門(1)HTMLAPP
- HTML5手機APP開發入門(2)HTMLAPP
- 深入理解 iOS App 的啟動過程iOSAPP
- iOS開發 APP啟動過程iOSAPP
- iOS App從點選到啟動iOSAPP
- iOS APP啟動頁載入廣告iOSAPP
- iOS 之獲取APP與手機 資訊iOSAPP
- 如何實現 iOS App 的冷啟動優化iOSAPP優化
- iOS-APP的啟動流程和生命週期iOSAPP
- 如何精確度量 iOS App 的啟動時間iOSAPP
- ios買球app推薦 蘋果手機買球的app有哪些iOSAPP蘋果
- android APP開機自動啟動AndroidAPP
- 教你動手做一個iOS越獄appiOSAPP
- iOS APP啟動-Main函式之前的那些事兒iOSAPPAI函式
- 設定手機開機就啟動程式的類
- iOS App Icon和啟動圖尺寸配置iOSAPP
- iOS APP啟動廣告實現方式 與 APP喚端呼叫iOSAPP
- Appium(Python)驅動手機淘寶AppAPPPython
- 京東在html5頁面中開啟本地app的解決方案HTMLAPP
- IOS基礎-APP圖示、啟動頁、名字的設定iOSAPP
- Appium 在 IOS 真機測試時啟動應用後經常卡死APPiOS
- iOS效能優化 - APP啟動時間優化iOS優化APP
- iOS學習筆記01 APP啟動相關iOS筆記APP
- 從mixin機制理解Flutter App啟動FlutterAPP
- 魔方淘寶客系統(網站+手機app)支援移動android+ios版網站APPAndroidiOS
- iOS App冷啟動治理:來自美團外賣的實踐iOSAPP
- 移動支付時代的手機和app安全設定APP
- VAIO啟動智慧手機業務 將釋出5英寸安卓手機AI安卓
- Android 中如何計算 App 的啟動時間?AndroidAPP