iOS中使用schema协议调用APP和使用iframe打开APP的例子
在iOS中,需要调起一个app可以使用schema协议,这是iOS原生支持的,并且因为iOS系统中都不能使用自己的浏览器内核,所以所有的浏览器都支持,这跟android生态不一样,android是可以自己搞内核的,但是iOS不行。
在iOS中提供了两种在浏览器中打开APP的方法:SmartAppBanner和schema协议。
SmartAppBanner
即通过一个meta标签,在标签上带上app的信息,和打开后的行为,例如:app-id之类的,代码形如:
<metaname="apple-itunes-app"content="app-id=myAppStoreID,affiliate-data=myAffiliateData,app-argument=myURL">
具体可以看下开发文档: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在iOS系统中打开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); }