Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

xiao333ma/XMWebView

Repository files navigation

XMWebView

CI Status Version License Platform

一个轻量级的 Hybrid 框架

Native -> JS

WKWebView 调用 JS 只有一个 evaluateJavaScript:completionHandler: 方法,JS 调用 Native 需要两步

JS -> Native

  1. 通过 WKUserContentControlleraddScriptMessageHandler: 方法注册一个 MessageHandler
  2. JS 通过 window.webkit.messageHandlers.XM_JS2Native.postMessage(parameters); 来调用到 Native。

该框架只是对这两个方法的封装,以更加统一的方式,来打通 Native - JS

封装之后,框架如下 info

JSAssembler

JS 组装器,用来组装 Native 调用 JS 字符串, XMWebViewJSDefaultAssembler 实现了 XMWebViewJSAssemblerProtocol 协议,提供了一个默认的组装器

 XM_Native2JS({name: foo, 
 params:{
 foo1: bar1,
 foo2: bar2,
 }});

可以实现 XMWebViewJSAssemblerProtocol 来定义自己的组装器

JSInvoker

JSInvoker 会把每一个 JS 调用封装为 XMWebViewJSInvokeOperation 放到队列里来执行,队列有两个, invokJSQueueWithLoadingState 会在 webView loading 结束之后,开始执行;invokJSQueueIgnoreLoadingState 则会直接执行

XMWebViewJSDispatcher

XMWebViewJSDispatcher 是一个派发器,派发 JS 调用 Native 的方法。

JSParser

XMWebViewJSDefaultJSParser 实现了 XMWebViewJSParserProtocol 协议,来解析 JS 传过来的数据,该解析器解析如下默认数据

JS 调用 Native 的数据格式如下

 XM_JS2Native({name: foo, 
 params:{
 foo1: bar1,
 foo2: bar2,
 }});

Native 收到的回调数据如下

message.body = @{
 name: foo
 params: @{
 foo1: bar1,
 foo2: bar2,
 }
 }

XMWebViewJSDefaultJSParser 将会解析出类名 XMWebViewFooHandler, 参数 @{@"foo1": bar1,@"foo2": bar2}

XMWebViewFooHandler 是一个继承自 XMWebViewJSDefaultHandlerOperationoperation,这 operation 会被加入主队列中执行

XMWebViewJSDefaultHandlerOperation

该类为处理业务逻辑的基类,应当继承与此类来处理自己的业务逻辑,该类已经处理好各种状态机,以及 JS 传递过来的参数的绑定,子类只需实现 -handleBusiness: 来处理自己的业务即可,当处理完成之后,调用 -callJSBackWithParams: 来回调给 JS

JSCallBackAssembler

XMWebViewJSDefaultCallBackAssembler 实现了 XMWebViewJSCallBackAssemblerProtocol 协议来构造一个 NSString,从而执行 JS。 用户可以实现自己的构造器来定义回调给 JS 的格式

webView 启动时 Native 主动注入一段 JS,来让 JS 调用 Native,Native 回调时会调用 window.XM_NativeCallBackNameMap.funcName(params) 来触发 MessageChannel 的 port1 发送消息,在 promise 中的 port2 的 onmessage 会被调用,然后执行 resolve

var XM_JS2Native_MessageChannelMap = {};
function XM_JS2Native(parameters) {
 var channel = new MessageChannel(); // 创建一个 MessageChannel
 if(!window.XM_NativeCallBackNameMap) {
 window.XM_NativeCallBackNameMap = {};
 }
 var id = parameters.name + "_" + Math.random();
 parameters.id = id;
 XM_JS2Native_MessageChannelMap[id] = channel;
 window.XM_NativeCallBackNameMap[parameters.name] = function(nativeValue) {
 if (nativeValue.id && XM_JS2Native_MessageChannelMap[nativeValue.id]) {
 XM_JS2Native_MessageChannelMap[nativeValue.id].port1.postMessage(nativeValue);
 delete XM_JS2Native_MessageChannelMap[nativeValue.id];
 }
 };
 window.webkit.messageHandlers.XM_JS2Native.postMessage(parameters);
 return new Promise(function(resolve, reject) {
 channel.port2.onmessage = function(e) {
 var data = e.data;
 resolve(data);
 channel = null;
 };
 });
}

使用方式

JS

XM_JS2Native({name: test, params:{foo1:bar1, foo2:bar2}}).then(nativeValue => {
 // 当 Native 回调的时候,这里会被出发
})

Native

XMWebViewTestHandler.h

@interface XMWebViewTestHandler : XMWebViewJSDefaultHandlerOperation
@end

XMWebViewTestHandler.m

#import "XMWebViewTestHandler.h"
@implementation XMWebViewTestHandler
- (void)handleBusiness {
 NSLog(@"param: %@", self.parameters);
 [self callJSBackWithParams:@{@"arg1": @"foo", @"arg2": @"bar"}];
}
@end

如有疑问,欢迎 issue

About

一个轻量化的 Hybrid 框架

Resources

License

Stars

Watchers

Forks

Packages

No packages published

AltStyle によって変換されたページ (->オリジナル) /