html与ios交互方法 WebViewJavascriptBridge
WebViewJavascriptBridge
1.html调用ios的方法
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
  <script>
    $(function () {
        //iOS用于js交互必备代码:
        function setupWebViewJavascriptBridge(callback) {
          if (window.WebViewJavascriptBridge) {
            return callback(WebViewJavascriptBridge);
          }
          if (window.WVJBCallbacks) {
            return window.WVJBCallbacks.push(callback);
          }
          window.WVJBCallbacks = [callback];
          var WVJBIframe = document.createElement('iframe');
          WVJBIframe.style.display = 'none';
          WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
          document.documentElement.appendChild(WVJBIframe);
          setTimeout(function () {
            document.documentElement.removeChild(WVJBIframe)
          }, 0)
        }
        // setupWebViewJavascriptBridge(function(bridge) {
        //     // native调用js
        //   // bridge.registerHandler('jsHandlerName', function(data, responseCallback) {
        //   //     // data为ObjC传递给JS的数据
        //   //     console.log("JS Echo called with:", data)
        //   //     // js返回数据给Objc
        //   //     responseCallback('返回一个字符串,告诉ObjC:我已收到数据data')
        //   // })
        //   // js调用native的方法
        //   bridge.callHandler('getUserCoorCallback', '获取用户位置信息经纬度的回调', function responseCallback(res) {
        //       // responseData返回的数据
        //       alert(res)
        //   })
        // })
        function getData(name,data){
          setupWebViewJavascriptBridge(function(bridge) {
            // native调用js
            // bridge.registerHandler('jsHandlerName', function(data, responseCallback) {
            //     // data为ObjC传递给JS的数据
            //     console.log("JS Echo called with:", data)
            //     // js返回数据给Objc
            //     responseCallback('返回一个字符串,告诉ObjC:我已收到数据data')
            // })
            // js调用native的方法
            bridge.callHandler(name,data, function responseCallback(res) {
                // responseData返回的数据
                alert('位置信息:'+res)
            })
          })
        }
        alert('执行1')
        getData('getUserCoorCallback', '获取用户位置信息经纬度的回调')
        alert('执行2')
    })
  </script>
</body>
</html>
打印结果
//执行1
//执行2
//位置信息: 22.581529;113971377
注意:setupWebViewJavascriptBridge是异步的,首先执行同步任务,再执行异步任务
$(function () {
  //iOS用于js交互必备代码:
  function setupWebViewJavascriptBridge(callback) {
    if (window.WebViewJavascriptBridge) {
      return callback(WebViewJavascriptBridge);
    }
    if (window.WVJBCallbacks) {
      return window.WVJBCallbacks.push(callback);
    }
    window.WVJBCallbacks = [callback];
    var WVJBIframe = document.createElement('iframe');
    WVJBIframe.style.display = 'none';
    WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
    document.documentElement.appendChild(WVJBIframe);
    setTimeout(function () {
      document.documentElement.removeChild(WVJBIframe)
    }, 0)
  }
  //native调用js
  setupWebViewJavascriptBridge(function (bridge) {
    bridge.registerHandler('articleDetailViewInit', function (data, responseCallback) {
      //字符串分割成一个数组
      responseCallback('文章详情界面初始化成功');
    })
  })
  //js调用native
  function rewardBtnClickCallback(uid) {
    WebViewJavascriptBridge.callHandler('rewardBtnClickCallback', uid, function (response) {
      alert('native被调用:' + response);
    });
  }
})
做个测试看看执行顺序
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
  <script>
    $(function () {
        //iOS用于js交互必备代码:
        function setupWebViewJavascriptBridge(callback) {
          alert('1')
          if (window.WebViewJavascriptBridge) {
            alert('7')
            return callback(WebViewJavascriptBridge);
          }
          if (window.WVJBCallbacks) {
            alert('8')
            return window.WVJBCallbacks.push(callback);
          }
          window.WVJBCallbacks = [callback];
          alert('2')
          var WVJBIframe = document.createElement('iframe');
          WVJBIframe.style.display = 'none';
          WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
          document.documentElement.appendChild(WVJBIframe);
          alert('3')
          setTimeout(function () {
            alert('4')
            document.documentElement.removeChild(WVJBIframe)
          }, 0)
        }
        function getData(name,data){
          setupWebViewJavascriptBridge(function(bridge) {
            alert(5)
            bridge.callHandler(name,data,function responseCallback(res) {
                alert(6)
                alert(res)
            })
          })
        }
        getData('getUserCoorCallback', '获取用户位置信息经纬度的回调')
    })
  </script>
</body>
</html>
执行顺序会按照alert 1-6 依次执行,不执行 7和8
再做测试 执行两次
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
  <script>
    $(function () {
        //iOS用于js交互必备代码:
        function setupWebViewJavascriptBridge(callback) {
          alert('1')
          if (window.WebViewJavascriptBridge) {
            alert('7')
            return callback(WebViewJavascriptBridge);
          }
          if (window.WVJBCallbacks) {
            alert('8')
            return window.WVJBCallbacks.push(callback);
          }
          window.WVJBCallbacks = [callback];
          alert('2')
          var WVJBIframe = document.createElement('iframe');
          WVJBIframe.style.display = 'none';
          WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
          document.documentElement.appendChild(WVJBIframe);
          alert('3')
          setTimeout(function () {
            alert('4')
            document.documentElement.removeChild(WVJBIframe)
          }, 0)
        }
        function getData(name,data){
          setupWebViewJavascriptBridge(function(bridge) {
            alert(5)
            bridge.callHandler(name,data,function responseCallback(res) {
                alert(6)
                alert(res)
            })
          })
        }
        getData('getUserCoorCallback', '获取用户位置信息经纬度的回调')
        getData('getUserCoorCallback', '获取用户位置信息经纬度的回调')
        // 执行顺序1 2 3 1 8 4  5 5 6 经纬度 6 经纬度
    })
  </script>
</body>
</html>
执行顺序按照1 2 3 1 8 4 5 5 6 经纬度 6 经纬度
2.vue调用ios的方法
步骤1.新建bridge.js文件
在src下新建lib目录 新建 bridge.js文件 也可以把文件放在config目录下
function setupWebViewJavascriptBridge (callback) {
  if (window.WebViewJavascriptBridge) {
    return callback(window.WebViewJavascriptBridge)
  }
  if (window.WVJBCallbacks) {
    return window.WVJBCallbacks.push(callback)
  }
  window.WVJBCallbacks = [callback]
  var WVJBIframe = document.createElement('iframe')
  WVJBIframe.style.display = 'none'
  WVJBIframe.src = 'https://__bridge_loaded__'
  document.documentElement.appendChild(WVJBIframe)
  setTimeout(function () {
    document.documentElement.removeChild(WVJBIframe)
  }, 0)
}
export default {
  callhandler (name, data, callback) {
    setupWebViewJavascriptBridge(function (bridge) {
      bridge.callHandler(name, data, callback)
    })
  },
  registerhandler (name, callback) {
    setupWebViewJavascriptBridge(function (bridge) {
      bridge.registerHandler(name, function (data, responseCallback) {
        callback(data, responseCallback)
      })
    })
  }
}
步骤2.引入bridge.js文件
方式1:全局引入
//main.js文件 //bridge.js放在lib目录下 // import Bridge from '../src/lib/bridge' Vue.prototype.$bridge = Bridge //bridge.js放在config目录下 import Bridge from '../config/bridge' Vue.prototype.$bridge = Bridge
方式2:局部引入
在组件内
<script>//对应bridge.js的路径
import Bridge from '../lib/bridge'
//或者
import Bridge from '../../config/bridge'export default{
}<script>
步骤3.使用
全局引入的方式
    //全局引入调用 对应步骤2的方式1
      this.$bridge.callhandler('getUserCoorCallback', "获取用户位置信息经纬度的回调", (data) => {
      // 处理返回数据
        alert(data)
       })
    //局部引入调用  对应步骤2的方式2
      Bridge.callhandler('getUserCoorCallback', "获取用户位置信息经纬度的回调", (data) => {
      // 处理返回数据
        alert(data)
      })
但是按照网上的方法以上步骤都无法获取到WebViewJavascriptBridge对象,
本人尝试在vue 根目录下的index.html文件上加上,然后马上执行setupWebViewJavascriptBridge(),才终于获取到WebViewJavascriptBridge对象,原因不明。有知道原因的朋友请解答一下。
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>活动</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
  <script>
    function setupWebViewJavascriptBridge(callback) {
        if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
        if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
        window.WVJBCallbacks = [callback];
        var WVJBIframe = document.createElement('iframe');
        WVJBIframe.style.display = 'none';
        WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
        document.documentElement.appendChild(WVJBIframe);
        setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
    }
    setupWebViewJavascriptBridge()
  </script>
</html>
补充:
第一次交互的时候,alert(this.$bridge)为Object
当我们尝试看看WebViewJavascriptBridge,alert(WebViewJavascriptBridge) 或 alert(window.WebViewJavascriptBridge)都是undefined,
本人马大哈,把方法名callhandler打callHandler了。因为export default导出的是一个对象,他有两个方法。1是callhandler(name,data,callback),2是registerhandler(name,callback)。
当一开始执行的时候WebViewJavascriptBridge是undefined,因为没有执行callhandler方法来执行 setupWebViewJavascriptBridge ,所以alert(WebViewJavascriptBridge) 是undefined。
执行完setupWebViewJavascriptBridge后,我们才能在ios中获取到WebViewJavascriptBridge对象,从而实现html与ios的交互。
    //错误
      this.$bridge.callHandler('getUserCoorCallback', "获取用户位置信息经纬度的回调", (data) => {
      // 处理返回数据
         alert(data)
       })
    //正确
       this.$bridge.callhandler('getUserCoorCallback', "获取用户位置信息经纬度的回调", (data) => {
      // 处理返回数据
         alert(data)
       })

html与ios交互方法 WebViewJavascriptBridge的更多相关文章
- iOS与HTML5交互方法总结(转)
		今天小编在找技术文章的时候,发现这样一个标题:iOS与HTML5交互方法总结,怎么看着这么熟悉呢? 还以为是刚哥用了别的文章,点进去一看,原来是刚哥自己写的文章,他们转载的,而且还上了Dev St ... 
- iOS与HTML5交互方法总结(修正)
		摘要 看了不少别人写的博客或者论坛,关于iOS与HTML5交互方法大概主要有5种方式: 1. 利用WKWebView进行交互(系统API) 2. 利用UIWebView进行交互(系统API) 3. 苹 ... 
- Unity3D与iOS消息交互方法(1)--iOS接收Unity3D发出的消息
		跨平台这种事情不管多NB, 总要有些与原生系统交互的方法, 比如 Unity3D与iOS消息交互方法. 一: 建立一个空的Unity工程. File --> New Project 二: 编 ... 
- OC与JS交互之WebViewJavascriptBridge
		上一篇文章介绍了通过UIWebView实现了OC与JS交互的可能性及实现的原理,并且简单的实现了一个小的示例DEMO,当然也有一部分遗留问题,使用原生实现过程比较繁琐,代码难以维护.这篇文章主要介绍下 ... 
- h5与安卓、ios交互
		1.安卓交互 h5调用安卓方法 window.webview.xxx() 安卓调用h5方法, 方法需要在全局注册 window['showUnreadMsg'] = () => { this.$ ... 
- UNITY3D与iOS交互解决方案
		原地址:http://bbs.18183.com/thread-456979-1-1.html 本帖最后由 啊,将进酒 于 2014-2-27 11:17 编辑 “授人以鱼,不如授人以渔”,以UNIT ... 
- Unity与IOS交互
		Unity IOS交互 @By 广州小龙 QQ群:63438968 环境:Mac os 10.9.2 Unity 4.2.1f4 Xcode 5.0.2 Unity IOS的交互我写过一个教程 ... 
- js和android及ios交互
		Android中Java和JavaScript交互 这种交互,Hybrid App 会用的比较多一点, 本文将介绍如何实现Java代码和Javascript代码的相互调用. Android提供了一个很 ... 
- Unity与安卓IOS交互
		记录下 安卓与Unity交互中 跳坑 找到的资料. <1>建立交互 http://blog.csdn.net/lizhengwei1989/article/details/54631 ... 
随机推荐
- SQL 高级查询(层次化查询,递归)
			SQL 高级查询 前面我们写了一下 SQL 的极简入门,今天来说点高级查询.没看到的朋友可以点击下面链接查看. 1 小时 SQL 极速入门(一) 1 小时 SQL 极速入门(二) 1 小时 SQL 极 ... 
- [Inside HotSpot] Visual Studio2017编译调试openjdk12
			编译 下载并编译好freetype,然后安装cygwin并安装必要工具: autoconf make zip unzip 当前目录效果为: 然后cygwin打开,进入openjdk12目录输入命令进行 ... 
- 【源码学习】redux-thunk
			阅读 redux 源码之后,想要加深一下对中间件的理解,于是选择 redux-thunk(2.3.0)这个源码只有十几行的中间件. 之前 redux 的学习笔记 https://www.cnblogs ... 
- Google 工程师:为什么 CDN 对移动客户端加速“没有”效果
			王者荣耀是近两年来比较火的手游,不少小伙伴都有玩过.玩这个游戏最怕的不是遇到猪一般的队友,也不是怕遇到神一样的对手.最让我们感到害怕和绝望的是,团战爆发时,而你 460 了.460 是一个玩家常用的词 ... 
- Entity Framework 异常: 'OFFSET' 附近有语法错误。\r\n在 FETCH 语句中选项 NEXT 的用法无效。
			在使用 EF 的时候,突然发现更新后在服务器中运行出错,异常信息主要包含以下信息: 'OFFSET' 附近有语法错误.\r\n在 FETCH 语句中选项 NEXT 的用法无效.\r\n关键字 'AS' ... 
- 广告等第三方应用嵌入到web页面方案 之 使用iframe嵌入
			有些项目中可能会遇到这样的需求, 需要在一个项目中嵌入其他的项目的页面或者功能.并且需要这两个页面之间能够进行交互. 本文主要介绍如何实现这种第三方应用的嵌入, 主要有以下几个方向: 1.iframe ... 
- Asp.Net Core WebApi中接入Swagger组件(初级)
			开发WebApi时通常需要为调用我们Api的客户端提供说明文档.Swagger便是为此而存在的,能够提供在线调用.调试的功能和API文档界面. 环境介绍:Asp.Net Core WebApi + S ... 
- 2.3Options建立配置和实体的映射「深入浅出ASP.NET Core系列」
			希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,谢谢关注. Startup.cs中创建MVC中间件 关键代码:services.AddMvc();app.UseMvcWith ... 
- Python编程从入门到实践笔记——变量和简单数据类型
			Python编程从入门到实践笔记——变量和简单数据类型 #coding=gbk #变量 message_1 = 'aAa fff' message_2 = 'hart' message_3 = &qu ... 
- .Net Framework项目引用.NetStandard标准库出现版本冲突解决办法
			今天在工作中出现一个引用问题,害我找问题找了很久.起因是在一个Winform项目下需要引用一个.NetStandard标准库,标准库引用了System.ComponentModel.Annotatio ... 
