服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - iOS中使用schema协议调用APP和使用iframe打开APP的例子

iOS中使用schema协议调用APP和使用iframe打开APP的例子

2020-12-16 15:07iOS开发网 IOS

这篇文章主要介绍了iOS中使用schema协议调用APP和使用iframe打开APP的例子,用在浏览器中打开APP,需要的朋友可以参考下

iOS中,需要调起一个app可以使用schema协议,这是iOS原生支持的,并且因为iOS系统中都不能使用自己的浏览器内核,所以所有的浏览器都支持,这跟android生态不一样,android是可以自己搞内核的,但是iOS不行。

在iOS中提供了两种在浏览器中打开APP的方法:Smart App Banner和schema协议。

Smart App Banner

即通过一个meta 标签,在标签上带上app的信息,和打开后的行为,例如:app-id之类的,代码形如:

复制代码 代码如下:
<meta name="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
今天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关于iOS自适应cell行高的那些事儿

    关于iOS自适应cell行高的那些事儿

    这篇文章主要给大家介绍了关于iOS自适应cell行高的那些事儿,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    daisy6092021-05-17
  • IOSIOS 屏幕适配方案实现缩放window的示例代码

    IOS 屏幕适配方案实现缩放window的示例代码

    这篇文章主要介绍了IOS 屏幕适配方案实现缩放window的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要...

    xiari5772021-06-01
  • IOSIOS开发之字典转字符串的实例详解

    IOS开发之字典转字符串的实例详解

    这篇文章主要介绍了IOS开发之字典转字符串的实例详解的相关资料,希望通过本文能帮助到大家,让大家掌握这样的方法,需要的朋友可以参考下...

    苦练内功5832021-04-01
  • IOS解析iOS开发中的FirstResponder第一响应对象

    解析iOS开发中的FirstResponder第一响应对象

    这篇文章主要介绍了解析iOS开发中的FirstResponder第一响应对象,包括View的FirstResponder的释放问题,需要的朋友可以参考下...

    一片枫叶4662020-12-25
  • IOSiOS通过逆向理解Block的内存模型

    iOS通过逆向理解Block的内存模型

    自从对 iOS 的逆向初窥门径后,我也经常通过它来分析一些比较大的应用,参考一下这些应用中某些功能的实现。这个探索的过程乐趣多多,不仅能满足自...

    Swiftyper12832021-03-03
  • IOSiOS 雷达效果实例详解

    iOS 雷达效果实例详解

    这篇文章主要介绍了iOS 雷达效果实例详解的相关资料,需要的朋友可以参考下...

    SimpleWorld11022021-01-28
  • IOSiOS中tableview 两级cell的展开与收回的示例代码

    iOS中tableview 两级cell的展开与收回的示例代码

    本篇文章主要介绍了iOS中tableview 两级cell的展开与收回的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    J_Kang3862021-04-22
  • IOSiOS布局渲染之UIView方法的调用时机详解

    iOS布局渲染之UIView方法的调用时机详解

    在你刚开始开发 iOS 应用时,最难避免或者是调试的就是和布局相关的问题,下面这篇文章主要给大家介绍了关于iOS布局渲染之UIView方法调用时机的相关资料...

    windtersharp7642021-05-04