iOS中使用schema协议调用APP和使用iframe打开APP的例子
在iOS中,需要调起一个app可以使用schema协议,这是iOS原生支持的,并且因为iOS系统中都不能使用自己的浏览器内核,所以所有的浏览器都支持,这跟android生态不一样,android是可以自己搞内核的,但是iOS不行。
在iOS中提供了两种在浏览器中打开APP的方法:SmartAppBanner和schema协议。
SmartAppBanner
即通过一个meta标签,在标签上带上app的信息,和打开后的行为,例如:app-id之类的,代码形如:
具体可以看下开发文档:https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html
今天SmartAPPBanner不是我们的主角,我们说的是schema
使用schemaURL来打开iOSAPP
schema类似自定义url协议,我们可以通过自定义的协议来打开自己的应用,形如:
myapplink://
#例如facebook的
fb://
#itunes的
itms-apps://
#还有短信也是类似的
sms://
如果要打开一个app,最简单的方式是通过一个链接,如我们在html中这样写:
<ahref="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的onload事件啊,可是遗憾的说,无效!所以我们找到了定时器(setTimeout),通过一个定时器,如果在一段时间内(比如500ms),当点击了按钮(记录time1),页面没有切走(调起app之后,页面进程会被中断),进程中断,那么计时器也会中断,这时候应该不会触发timer,如果调起失败,那么timer会就触发,我们判断下在一定时间内如果页面没有被切走,就认为调起失败。
另外通过timer触发时候的timer2,做差,判断是否太离谱了(切走了之后的时间应该比timer实际定时的500ms要长):
functionopenIos(url,callback){
if(!url){
return;
}
varnode=document.createElement("iframe");
node.style.display="none";
varbody=document.body;
vartimer;
varclear=function(evt,isTimeout){
(typeofcallback==="function")&& callback(isTimeout);
if(!node){
return;
}
node.onload=null;
body.removeChild(node);
node=null;
};
varhide=function(e){
clearTimeout(timer);
clear(e,false);
};
node.onload=clear;
node.src=url;
body.appendChild(node);
varnow=+newDate();
//如果事件失败,则1秒设置为空
timer=setTimeout(function(){
varnewTime=+newDate();
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调用schemaURL
2.使用定时器判断在一段时间内是否调起成功
3.使用pageshow和pagehide来辅助定时器做更详细的判断
4.定时器中如果有alert可能不会被弹出,这一点很吃惊!后面的dom竟然5.执行了,但是alert没弹出,可能跟alert的实现有关系吧
6.在实验中我使用了两个定时器,是因为切回浏览器之后,有时候timeout触发要在pagehide和pageshow之前
7.计算timer实际执行时间差,也是不靠谱的
最后附上研究的代码,算是比较靠谱的方法了,虽然还是有一定的失败(第三方浏览器pagehide和pageshow不触发):
<p><buttonid="btn">点我点我啊!alert,不会弹出</button></p>
<p><buttonid="btn2">点我点我啊!alert2,虽然有alert和info,info执行,但是alert不弹出</button></p>
<p><buttonid="btninfo">点我点我啊!info可以</button></p>
$(function(){
var$info=$("#info");
functioninfo(msg){
varp=$("<p>"+msg+"</p>");
$info.append(p);
}
$("#btn").on("click",function(){
openIos("baiduboxapp://",function(t){
if(t){
alert("timeoutornobaiduAPP");
}else{
alert("invokesuccess");
}
});
});
$("#btn2").on("click",function(){
openIos("baiduboxapp://",function(t){
if(t){
info("timeoutornobaiduAPP2");
alert("timeoutornobaiduAPP2");
}else{
info("invokesuccess2");
alert("invokesuccess2");
}
});
});
$("#btninfo").on("click",function(){
openIos("baiduboxapp://",function(t){
if(t){
info("timeoutornobaiduAPP");
}else{
info("invokesuccess");
}
});
});
});
functionopenIos(url,callback){
if(!url){
return;
}
varnode=document.createElement("iframe");
node.style.display="none";
varbody=document.body;
vartimer;
varclear=function(evt,isTimeout){
(typeofcallback==="function")&& callback(isTimeout);
window.removeEventListener("pagehide",hide,true);
window.removeEventListener("pageshow",hide,true);
if(!node){
return;
}
node.onload=null;
body.removeChild(node);
node=null;
};
varhide=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);
varnow=+newDate();
//如果事件失败,则1秒设置为空
timer=setTimeout(function(){
timer=setTimeout(function(){
varnewTime=+newDate();
if(now-newTime>1300){
clear(null,false);
}else{
clear(null,true);
}
},1200);
},60);
}
相关文章
- iOS-最全的App上架教程
- 手机网页调试工具-兼容IOS与安卓
- IOS开发之——Position和AnchorPoint(92)「建议收藏」
- 《一步步了解iOS APP上架流程,让你的APP顺利进入App Store的大门》
- App自动化测试|原生app元素定位方法
- 无mac电脑生成ios打包证书的方法
- IOS – OPenGL ES 设置图像亮度 GPUImageBrightnessFilter
- IOS – OpenGL ES 调节图像色彩替换 GPUImageFalseColorFilter
- ios发布证书用于上架app_腾讯新闻
- app提交上架最新流程 ios
- StoreKit:iOS应用内推广其他App
- 如何在IOS上发布APP最新教程
- 实现在windows、linux下上传ios app到App Store
- app store/ios开发证书、发布证书、推送证书的快捷制作
- 《简化iOS APP上架流程,App Uploader助你搞定!》
- IOS网络编程—(数据请求+slider)将网络上的大文件下载到本地,并打印其进度详解手机开发
- IOS计算器的实现详解手机开发
- iOS获取当前app版本详解手机开发
- iOS开发UI篇—CALayer详解手机开发
- 探索Linux系统:在iOS上下载(linux系统ios下载)
- 苹果在iOS 14.7开发者测试版本中修复了Wi-Fi功能变砖的问题
- 极速开发APP与MySQL的无缝连接(app 如何连mysql)