天天看點

JSBridge,JavaScript和原生Native 互動,iOS和HTML5互動

大家好,我是OB。

故不積窪步,無以至千裡。今天給大家分享一下native和js的互動。

用到了一個小工具:

OBJSBridge

支援pod 內建 :

pod 'OBJSBridge'

如果不想用pod,也可以直接把源碼拖到項目中去。隻需要

OBJSBridge.h

OBJSBridge.m

就可以了。代碼位址

記得star喲。

一、OBJSBridge簡單介紹及使用

最近項目中加載了很多HTML頁面,是以

native

js

的互動顯得格外重要。

最主要運用場景是:用戶端登入,如何把使用者的登入資訊傳遞給

js

;另一面在商品詳情頁(

html

)中選購的商品

id

如何傳遞給

native

,在原生頁面發起訂單及付款;

1. OC 向 JS 傳遞參數,可以是字典,也可以是字元串。

JSBridge,JavaScript和原生Native 互動,iOS和HTML5互動

代碼如下

注意:動态向

js

傳入參數,需要把握時機,就是等到

textfield.text

有值了,再向

js

中注入方法。

當方法注入了js中,js就可以直接使用方法了。

if (typeof(pushUserId) === 'function') {
        this.info = pushUserId(); 
      }
           

pushUserId()

這裡就是

oc

注入的方法,

js

直接使用。該方法的傳回值就是

oc

傳過去的參數。

2. JS 向OC傳遞參數,可以是字典,也可以是字元串。

前提是oc向js中注入方法,該方法有回調,

[[OBJSBridge shareBridge] registerReceiveFunction:@"getJSProductUser"  webView:self.wkwebView   didReceiveScriptMessage:^(WKScriptMessage * _Nonnull message) {
        NSLog(@"getJSProductUser:%@",message.body);
    }];

           

b:方法注冊完成後,js直接調用方法,并傳遞參數。

if (typeof(getJSProductUser) === 'function') {
        getJSProductUser({"userName":"lishuyang","usreID":"32345"});
}
           

getJSProductUserr({"userName":"lishuyang","usreID":"32345"})

該方法也可在js直接調用,因為oc已經将方法注入到js中。

可在控制台看到js傳過來的參數

JSBridge,JavaScript和原生Native 互動,iOS和HTML5互動
JSBridge,JavaScript和原生Native 互動,iOS和HTML5互動

二、OBJSBridge原理

Native與JS互動主要的兩種方式:

  1. 攔截url(适用于UIWebView和WKWebView)
  2. WKScriptMessageHandler(隻适用于WKWebView,iOS8+)

今天隻說說第二種:

- (void)setupWebView{
    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    configuration.userContentController = [[WKUserContentController alloc] init];
    [configuration.userContentController addScriptMessageHandler:self name:@"printFunc"];
    
    WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];
    webView.UIDelegate = self;
    
}

           

1:WKUserContentController

WKUserContentController

主要是用于js互動的控制器,下面是官方的介紹

@interface WKUserContentController : NSObject <NSSecureCoding>

@property (nonatomic, readonly, copy) NSArray<WKUserScript *> *userScripts;

//添加js方法
- (void)addUserScript:(WKUserScript *)userScript;
- (void)removeAllUserScripts;

//添加js方法,并注冊回調函數
- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;
- (void)removeScriptMessageHandlerForName:(NSString *)name;
@end
           

官方文檔中可以看出:

WKUserContentController

可以編寫js相關的代碼,并注冊回調。那麼我們這裡也是利用這一點。在執行個體化

WKWebView

的時候,向他的

WKWebViewConfiguration

中添加我們的

WKUserContentController

,并add添加js相關代碼。然後在

WKScriptMessageHandler

代理中,拿到回調

2:WKScriptMessageHandler

WKScriptMessageHandler

是一個協定,用來回調js的

@protocol WKScriptMessageHandler <NSObject>
@required

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

@end
           

那麼最終js響應後的資料回到native時,該代理方法可以收到message

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message 
{
	//message.name  對應上面注冊的方法name
	//message.body  具體的值
}
           
@interface WKScriptMessage : NSObject

@property (nonatomic, readonly, copy) id body;
@property (nullable, nonatomic, readonly, weak) WKWebView *webView;
@property (nonatomic, readonly, copy) WKFrameInfo *frameInfo;
@property (nonatomic, readonly, copy) NSString *name;
@end

           

繼續閱讀