大家好,我是OB。
故不積窪步,無以至千裡。今天給大家分享一下native和js的互動。
用到了一個小工具:
OBJSBridge
支援pod 內建 :
pod 'OBJSBridge'
如果不想用pod,也可以直接把源碼拖到項目中去。隻需要
OBJSBridge.h
OBJSBridge.m
就可以了。代碼位址
記得star喲。
一、OBJSBridge簡單介紹及使用
最近項目中加載了很多HTML頁面,是以
native
和
js
的互動顯得格外重要。
最主要運用場景是:用戶端登入,如何把使用者的登入資訊傳遞給
js
;另一面在商品詳情頁(
html
)中選購的商品
id
如何傳遞給
native
,在原生頁面發起訂單及付款;
1. OC 向 JS 傳遞參數,可以是字典,也可以是字元串。
代碼如下
注意:動态向
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傳過來的參數
二、OBJSBridge原理
Native與JS互動主要的兩種方式:
- 攔截url(适用于UIWebView和WKWebView)
- 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