資料互動實作參照(本方案以vue為例介紹):
https://blog.csdn.net/qq_44393166/article/details/105097286
https://blog.csdn.net/lyyo_cd/article/details/84304864
https://www.jianshu.com/p/f63bab6c90e0
首先通過以下方法確認登錄設備為Android還是iOS,如果是iOS可進一步判斷是否為iPad
(由于有些iPad內核顯示使用了macOS系統,所以這里用觸點區分,如有更好的方案可替代)
// iPad可能裝載Mac OS
export function isIPad() {
var userAgentInfo = navigator.userAgent
var Agents = ['iPad','Mac']
var flag = false
var v = 0
for (; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
// iPad觸點為5 Mac為0
if (navigator.maxTouchPoints==0) {
flag = "Mac"
}else{
flag = "iPad"
}
break
}
}
return flag
}
export function mobileInfo() {
var u = navigator.userAgent
if (u.indexOf('Android') > -1 || u.indexOf('Linux') > -1) {
//安卓手機
return '安卓'
} else if (u.indexOf('iPhone') > -1) {
//蘋果手機
return '蘋果'
} else if (u.indexOf('Windows Phone') > -1) {
//winphone手機
return 'winphone'
}
}
隨后可通過以下方法完成與安卓、ios的資料互通,
// 訪問ios、安卓
const sysInfo = mobileInfo()
const isIPadInfo = isIPad() == 'iPad'
// 呼叫原生方法(無回呼)
export function setFn(methods, params) {
if (params == null) {
if (sysInfo == '安卓') {
window.android[methods]()
}
if (sysInfo == '蘋果' || isIPadInfo) {
window.webkit.messageHandlers[methods].postMessage('')
}
} else {
let data = params
if (typeof data !== 'string') data = JSON.stringify(data)
if (sysInfo == '安卓') {
window.android[methods](data)
}
if (sysInfo == '蘋果' || isIPadInfo) {
window.webkit.messageHandlers[methods].postMessage(data)
}
}
}
// 呼叫原生方法(有回呼)
export function set(methods, params, fn) {
let fName = methods + 'Jg'
get([{ [fName]: fn }])
if (params == null) {
if (sysInfo == '安卓') {
window.android[methods]()
}
if (sysInfo == '蘋果' || isIPadInfo) {
window.webkit.messageHandlers[methods].postMessage()
}
} else {
let data = params
if (typeof data !== 'string') data = JSON.stringify(data)
if (sysInfo == '安卓') {
window.android[methods](data, fName)
}
if (sysInfo == '蘋果' || isIPadInfo) {
window.webkit.messageHandlers[methods].postMessage(data, fName)
}
}
}
// 提供方法給原生呼叫
export function get(fnArr) {
fnArr.forEach(el => {
for (var key in el) {
window[key] = el[key]
}
})
}
-
get的作用是web暴露給 android 與 ios 自己的方法
-
set與setFn的作用是web去使用 android 與 ios 提供的方法
因沒有找到web訪問移動端原生后回呼函式寫法、這里就模擬了回呼函式的方式,即:
采用原生提供的方法名+Jg的方式給原生層定義web提供的方法,并讓原生層執行,以達到回呼函式的目的,
使用原生方法時,就呼叫原生方法后邊的js邏輯不執行的問題,可采用 上述回呼函式 的方式激活方法,
原生呼叫vue中方法:
methods: {
// 測驗方法
ceshi() {
console.log("測驗方法1")
},
// 測驗方法
ceshi2() {
console.log("測驗方法2")
},
},
mounted() {
//暴露方法給安卓、ios
get( [{ ceshi: this.ceshi, ceshi2: this.ceshi2 }])
}
vue中呼叫原生方法:
methods: {
// 測驗方法
ceshi1() {
const _this = this//需要轉this
set('callAndroid', { test: '測驗' }, function(res) {
alert('接收到的' + res)
})
},
// 測驗方法
ceshi2() {
setFn('callAndroid', { test: '測驗' })
}
}
第一個引數為原生提供給web的方法名,
第二個引數為傳遞的引數,不傳參時寫null,
第三個引數為原生呼叫的該方法的回呼函式,
(setFn沒有第三個引數、只有set有)
Android呼叫web方法:
bridgeJavascript(){
let that = this;
window.WebViewJavascriptBridge.callHandler(
'ceshi1'//與web一起定義的共同方法名
,{} // 引數
,function(res){//web方法回傳值
res=JSON.parse(res);
alert(res)
}
)
}
Android提供方法給web呼叫:
window.WebViewJavascriptBridge.send( //提供方法名為send的方法給web呼叫
data //需要傳遞的訊息引數
,function(res){ //回傳的回應
alert(res)
}
)
iOS呼叫web方法:
// 呼叫JS方法
webView.evaluateJavaScript("ceshi1" + "('\(token)')") { (result, err) in
// result是JS回傳的值
print(result as? String ?? "" , err.description)
}
iOS提供方法給web呼叫:
// 提供方法給web呼叫
func addJsObj(_ key: String, _ value: String) {
wkwebview.evaluateJavaScript("vm.\(key) = \(value)", completionHandler: nil)
}
如果有更方便的寫法歡迎來討論,讓我們一起有條不紊的持續進步,
喜歡的話不妨點個小小的贊與關注,您的贊與關注將是我源源不斷的前進動力
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/184742.html
標籤:其他
