日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jsbridge实现及原理_如何实现一个优雅的jsBridge

發布時間:2024/10/8 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jsbridge实现及原理_如何实现一个优雅的jsBridge 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是jsbridge

jsbridge是客戶端和H5溝通的橋梁,通過它,我們可以獲取部分原生能力,同時客戶端也可以使用我們提供的一些方法。實現雙向通信。

jsbridge原理

客戶端可以通過webview里面注入一些javascript的上下文,可以理解為在window對象上掛載了一些方法,然后H5通過特定的對象可以獲取到這個方法,反過來也是一樣,js掛載了一些方法到window對象上,客戶端也就可以調用js的某些方法。

具體實現

方案一:注入API

IOS UIWebView

JSContext *context = [uiWebView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

context[@"postBridgeMessage"] = ^(NSArray *calls) {

// Native 邏輯

};

H5使用window.postBridgeMessage(message)調用

IOS WKWebView

@interface WKWebVIewVC ()

@implementation WKWebVIewVC

- (void)viewDidLoad {

[super viewDidLoad];

WKWebViewConfiguration* configuration = [[WKWebViewConfiguration alloc] init];

configuration.userContentController = [[WKUserContentController alloc] init];

WKUserContentController *userCC = configuration.userContentController;

// 注入對象,前端調用其方法時,Native 可以捕獲到

[userCC addScriptMessageHandler:self name:@"nativeBridge"];

WKWebView wkWebView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];

// TODO 顯示 WebView

}

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {

if ([message.name isEqualToString:@"nativeBridge"]) {

NSLog(@"前端傳遞的數據 %@: ",message.body);

// Native 邏輯

}

}

H5使用window.webkit.messageHandlers.nativeBridge.postMessage(message)方式調用。

來看一下H5端具體實現

假設我們需要一個getUserInfo方法,用于H5獲取當前APP登錄用戶的信息。

那么我們js可以這樣:

import registerCallback from '../registerCallback';

export default function getUserInfo() {

return new Promise((resolve, reject) => {

try {

window.webkit.messageHandlers.getUserInfo.postMessage({

callback: registerCallback(resolve),

});

} catch (e) {

reject(e);

}

});

}

我們定義一個getUserInfo方法,這個方法會去調用window.webkit.messageHandlers.getUserInfo.postMessage方法,這是客戶端寫入的方法,然后傳入一個callback方法??蛻舳藭ㄟ^callback方法把我們需要的信息返回給我們。

我們可以再看下registerCallback這個方法是什么:

window.knCallbacks = {};

function makeRandomId(func) {

return `${func.name || 'anonymous'}_${Date.now()}`;

}

export default function registerCallback(callback, keepAlive) {

if (!callback) {

return null;

}

const callbackId = makeRandomId(callback);

window.knCallbacks[callbackId] = (data) => {

let result;

if (typeof data === 'object') {

result = data;

} else if (typeof data === 'string') {

try {

result = JSON.parse(data);

} catch (e) {

result = data;

}

}

callback(result);

if (!keepAlive) {

delete window.knCallbacks[callbackId];

}

};

return `knCallbacks.${callbackId}`;

}

在這個方法里面,我們會為promise的resolve方法生成一個隨機函數名,避免出現window可能會有同名函數導致將其覆蓋的問題。 然后我們根據生成的函數名重寫一個函數,將這個函數最后返回給外部的callback,傳遞給了客戶端。 這里的data就是客戶端調用callback傳遞過來的數據。 我們在這里對數據做一些處理,然后給到callback,也就是promise的resolve。

Android

客戶端實現:

publicclassJavaScriptInterfaceDemoActivityextendsActivity{

private WebView Wv;

@Override

publicvoidonCreate(Bundle savedInstanceState){

super.onCreate(savedInstanceState);

Wv = (WebView)findViewById(R.id.webView);

final JavaScriptInterface myJavaScriptInterface = new JavaScriptInterface(this);

Wv.getSettings().setJavaScriptEnabled(true);

Wv.addJavascriptInterface(myJavaScriptInterface, "knJSBridge");

// TODO 顯示 WebView

}

publicclassJavaScriptInterface{

Context mContext;

JavaScriptInterface(Context c) {

mContext = c;

}

publicvoidpostMessage(String webMessage){

// Native 邏輯

}

}

}

H5實現

import registerCallback from '../registerCallback';

export default function getUserInfo() {

return new Promise((resolve, reject) => {

try {

window.knJSBridge.getUserInfo(JSON.stringify({

callback: registerCallback(resolve),

}));

} catch (e) {

reject(e);

}

});

}

這里我們其實可以看到,knJSBridge其實是我們和客戶端約定的一個字段。然后我們通過window.knJSBridge就可以調用客戶端的方法了。 registerCallback和IOS的是一樣的。

根據上面我們H5這里最后可以實現這樣一個結構的jsbridge

jsbridge

- index.js

- ios/

- index.js

- getUserInfo.js

- android/

- index.js

- getUserInfo.js

// jsbridge/index.js

import iosBridge from './iOs';

import androidBridge from './android';

export default class Bridge {

constructor() {

super();

if (isAndroid) {

this.jsbridge = androidBridge;

} else {

this.jsbridge = iosBridge;

}

}

getUserInfo = (...args) => this.jsbridge.getUserInfo(...args);

}

// ios/index.js

import getUserInfo from './getUserInfo';

export {

getUserInfo

}

// ios/getUserInfo.js

import registerCallback from '../registerCallback';

export default function getUserInfo() {

return new Promise((resolve, reject) => {

try {

window.webkit.messageHandlers.getUserInfo.postMessage({

callback: registerCallback(resolve),

});

} catch (e) {

reject(e);

}

});

}

// android/index.js

import getUserInfo from './getUserInfo';

export {

getUserInfo

}

// android/getUserInfo.js

import registerCallback from '../registerCallback';

export default function getUserInfo() {

return new Promise((resolve, reject) => {

try {

window.webkit.messageHandlers.getUserInfo.postMessage({

callback: registerCallback(resolve),

});

} catch (e) {

reject(e);

}

});

}

方案二:url攔截

這種方案就是H5構造一個iframe,通過給iframe設置src發起請求,然后客戶端攔截請求實現。

一般會將url設為一個特殊的字符串,比如https://__bridge__這個樣子,然后后面跟上我們需要傳遞的數據,包括一個callback函數名,客戶攔截這種請求,然后通過callback將數據傳遞回來。

前端收藏家(微信號: fedaily)

收集全網優秀前端技術資訊,與你分享,共同成長。

總結

以上是生活随笔為你收集整理的jsbridge实现及原理_如何实现一个优雅的jsBridge的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。