项目场景:uni-app,h5内嵌到原生app页面,获取token,跳转并调用原生app的方法
问题描述
需求是点击h5页面要跳转到原生app指定页面,但是看了网上的很多方法最终还是无法实现跳转和接收app的返回值
以下2个是网上的方法,自己试过之后还是无法实现效果,需要进行改动:
方法1;
H5调用IOS App方法
var query = {
title:'分享到好友',
desc:'快来看看吧'
}
window.webkit.messageHandlers.share.postMessage(JSON.stringify(query));
H5调用Android App方法
var query = {
title:'分享到好友',
desc:'快来看看吧'
}
window.android['share'](JSON.stringify(query));
方法2:
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
window.WVJBCallbacks = [callback]; // 创建一个 WVJBCallbacks 全局属性数组,并将 callback 插入到数组中。
var WVJBIframe = document.createElement('iframe'); // 创建一个 iframe 元素
WVJBIframe.style.display = 'none'; // 不显示
WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__'; // 设置 iframe 的 src 属性
document.documentElement.appendChild(WVJBIframe); // 把 iframe 添加到当前文导航上。
setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}
// 这里主要是注册 OC 将要调用的 JS 方法。
setupWebViewJavascriptBridge(function(bridge){
})
(方法2 我之前是直接写在script标签下试的,发现还是不行)
原因分析:
方法1.我在ios和Android 都打印了window,发现在ios app上没有找到window里面的share方法,在Android app上找不到window.android
方法2.可能是因为我放的位置不对
解决方案:
其实与app数据互通应该除了会用到webview外,还要用到ios和Android 的桥梁bridge(桥梁名)的。
–我是这样写的
第一步:(写在script下)
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
window.WVJBCallbacks = [callback]; // 创建一个 WVJBCallbacks 全局属性数组,并将 callback 插入到数组中。
var WVJBIframe = document.createElement('iframe'); // 创建一个 iframe 元素
WVJBIframe.style.display = 'none'; // 不显示
WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__'; // 设置 iframe 的 src 属性
document.documentElement.appendChild(WVJBIframe); // 把 iframe 添加到当前文导航上。
setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
}
–其中callNativeMethod为ios和Android 里面的方法,调用原生app 名为callNativeMethod的方法,获取该方法的返回值,我需要token,所以返回的是token
第二步:(我要token所以将一下代码写在onload里面,根据不同情况放在不同的位置)
let platform = uni.getSystemInfoSync().platform;
if(platform === "ios"){
setupWebViewJavascriptBridge(function(bridge){
//{'actionType':'token','params':null } 为ios方法需要传入的参数
//actionType 是类型,我传不同的值给app,他们会根据不用的值跳转到不同的页面,但是当传入‘token’字符串的时候不会跳转,而是return一个token给我,所以这个代码块我是放在onload的什么周期里面的。
bridge.callHandler('callNativeMethod',{'actionType':'token','params':null },function responseCallback(dataFromOC) {
this.token = dataFromOC
})
});
}else if(platform === "android"){
let content = bridge.callNativeMethod('token',null)
this.token = 'bearer '+content
}
以下是点击按钮跳转(放在点击事件里面)
fexBtnType(i,status){
// 这里主要是注册 OC 将要调用的 JS 方法。
let par = status+''
let platform = uni.getSystemInfoSync().platform;
if(platform === "ios"){
setupWebViewJavascriptBridge(function(bridge){
bridge.callHandler('callNativeMethod',{'actionType':par,'params':null })
});
}else if(platform === "android"){
bridge.callNativeMethod(par,null)
}
}
—总结:哪里需要与app进行交互或传参哪里就放这些代码,里面如有需要可以做适当改动