Skip to content

Commit 10c1c03

Browse files
Update README.md
1 parent 25a7cc2 commit 10c1c03

1 file changed

Lines changed: 21 additions & 234 deletions

File tree

‎README.md‎

Lines changed: 21 additions & 234 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,6 @@
77
![](https://img.shields.io/badge/language-objc-orange.svg)
88
![ARC](https://img.shields.io/badge/ARC-orange.svg)
99

10-
## 版本说明:
11-
1.`release 0.0.6`:由于苹果近期给开发者邮件说明,要求尽快删除UIWebView等相关API,因此新增release 0.0.6版本,删除UIWebView的支持。
12-
13-
2.`release 0.1.0`:增加`WKJSBridge.js`,对JS侧接口做了完善,统一入口,提供参数传递,成功、失败回调。
14-
15-
3.`release 0.1.3`:将`WKJSBridge.js`拆分为`wk_bridge_ interface.js`和`wk_bridge_channel.js`,分别负责对h5暴漏接口和js-native通信使用。`wk_bridge_ interface.js`属于业务层,不包含在`pod`内,属于业务方自定义扩展使用,具体可以参考demo。
16-
1710

1811
## Link
1912
* Blog :
@@ -27,258 +20,52 @@
2720
[《写一个易于维护使用方便性能可靠的Hybrid框架(一)—— 思路构建》](https://juejin.im/post/5c07d95ee51d451d930b04c7)
2821

2922

30-
## 介绍
31-
32-
**iOS 基于WKWebView的JS-Native交互框架,功能强大,轻松集成,一行代码即可,业务框架分离,易于拓展,致力于让h5调用native像调用一个接口那样简单。**
33-
**关于通信方案说明:**
34-
* WKWebView使用`addScritMessageHandler`构建通信,苹果提供的bridge,可以理解为亲儿子,好处自然不用多说。
35-
36-
**架构图**
37-
38-
![image text](https://github.com/GitWangKai/WKJavaScriptBridge/blob/master/img.jpg)
39-
40-
41-
**类图**
42-
43-
![image text](https://github.com/GitWangKai/WKJavaScriptBridge/blob/master/img_1.jpg)
44-
4523
## 特性
46-
- 一行代码即可让WebView能力无限。
47-
- 支持h5扩展自定义插件。
48-
- 插件化JS-Native业务逻辑,业务完全分离,最大化解耦。
49-
- 支持在不影响原业务的情况下,集成超简单。(相当于在不影响原bridge的情况下新搭建了个bridge供h5使用)
50-
- 支持业务模块异步回调。
51-
- 基于__attribute( )函数进行插件白名单注册,业务模块的注册只需要在自己内部注册即可,摆脱plist等传统注册方式。目前已知[阿里BeeHive](https://github.com/alibaba/BeeHive)/[美团Kylin组件](https://juejin.im/post/5c0a17d6e51d4570cf60d102)皆使用此方式进行注册。
52-
- 针对WKWebView进行了Cookie丢失处理。
53-
- 针对WKWebView白框架屏问题进行了处理。
54-
- 针对WKWebView所带来的一些Crash问题进行了容错处理。
55-
56-
57-
## 安装
5824

59-
### 1.手动导入
25+
- 一行代码集成。
26+
- 支持业务分离,支持模块化开发。
27+
- 异步调用。
28+
- 支持业务模块白名单机制,提升安全性。
6029

61-
下载WKJavaScriptBridge文件夹,将WKJavaScriptBridge文件夹拖入到你的工程中。
6230

63-
### 2.CocoaPods
64-
1. 在 Podfile 中添加 `pod 'WKJavaScriptBridge', '~> 0.1.3'`。
65-
2. 执行 `pod install` 或 `pod update`。
66-
3. native侧导入 `<WKWebViewEngine.h>`。
67-
4. js侧引入`wk_bridge_channel.js`,如果使用了类似于demo的`wk_bridge_ interface.js`,只需引入`wk_bridge_ interface.js`即可。
68-
69-
70-
## 用法
71-
`WKWebViewEngine`是框架的主体类,对外提供`bindBridgeWithWebView:withDelegate:`接口,用来拦截webView的代理函数。具体参照demo。
31+
## 安装
7232

73-
### 1.使用框架
33+
### 方法一:Cocoapods
34+
- 1、:
7435

7536
```objc
76-
// WKWebView
77-
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
78-
WKPreferences *preferences = [WKPreferences new];
79-
preferences.javaScriptCanOpenWindowsAutomatically = YES;
80-
preferences.minimumFontSize = 40.0;
81-
configuration.preferences = preferences;
82-
WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];
83-
webView.navigationDelegate = self;
84-
/***/
85-
[WKWebViewEngine bindBridgeWithWebView:webView withDelegate:self];
86-
/***/
87-
[self.view addSubview:webView];
88-
NSString *urlStr = [[NSBundle mainBundle] pathForResource:@"index.html" ofType:nil];
89-
NSURL *fileURL = [NSURL fileURLWithPath:urlStr];
90-
if (@available(iOS 9.0, *)) {
91-
[webView loadFileURL:fileURL allowingReadAccessToURL:fileURL];
92-
} else {
93-
// Fallback on earlier versions
94-
}
37+
在Podfile文件里面添加:pod 'WKJavaScriptBridge'
9538
```
96-
97-
98-
### 2.自定义业务插件(原生侧)
99-
100-
2.1. 创建插件类,继承自`WKBasePlugin`。
101-
2.2. 插件类里面添加`@WKRegisterWebPlugin`宏,暂时用于插件是否需要提前初始化,加快第一次调用速度。也可以扩充一些其他功能。
102-
2.3. 插件里构建业务逻辑,通过`sendPluginResult:callbackId:`函数把结果回传给JS侧。
39+
- 2、:对应文件添加头文件
10340

10441
```objc
105-
#import "WKBasePlugin.h"
106-
@interface WKFetchPlugin : WKBasePlugin
107-
- (void)nativeFentch:(WKMsgCommand *)command;
108-
@end
109-
42+
#import "WKJavaScriptBridge.h"
11043
```
11144

112-
```objc
113-
@WKRegisterWebPlugin(WKFetchPlugin)
114-
115-
@implementation WKFetchPlugin
116-
- (void)nativeFentch:(WKMsgCommand *)command {
117-
NSString *method = [command.arguments objectForKey:@"method"];
118-
NSString *url = [command.arguments objectForKey:@"url"];
119-
120-
NSLog(@"method : %@ ; url : %@", method, url);
121-
122-
WKPluginResult *result = [WKPluginResult resultWithStatus:WKCommandStatus_ERROR messageAsDictionary:@{@"result": @"success!!"}];
123-
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
124-
}
45+
### 方法二:手动添加
46+
- 1、下载WKJavaScriptBridge,将WKJavaScriptBridge文件夹拖入到你的工程中
12547

126-
@end
127-
```
128-
2.4.构建配置native端插件:用于给js调用,(iOS & android)两端需要相同的serviceId和actionId,才能启动相同的事件。
129-
```objc
130-
@interface WKJSBridgeConfig : WKBasePlugin
131-
- (void)fetchConfig:(WKMsgCommand *)command;
132-
@end
133-
```
48+
- 2、引入头文件:
13449

13550
```objc
136-
@WKRegisterWebPlugin(WKJSBridgeConfig)
137-
138-
@implementation WKJSBridgeConfig
139-
140-
- (void)fetchConfig:(WKMsgCommand *)command {
141-
NSDictionary *dict = @{
142-
@"fetch_id":@{//服务ID
143-
@"service":@"WKFetchPlugin",
144-
@"action":@{//具体事件
145-
@"action_get":@"nativeGet",
146-
@"action_post":@"nativePost"
147-
}
148-
}
149-
};
150-
WKPluginResult *result = [WKPluginResult resultWithStatus:WKCommandStatus_OK messageAsDictionary:dict];
151-
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
152-
}
153-
@end
154-
```
155-
156-
这样一个插件就定义完毕了:插件的意思就是独立的,与其他功能模块无耦合的业务模块,用来处理一类JS-Native的交互。例如JS想要获取地图信息、wifi信息、文件处理等都可以定义为一个插件。插件的好处就是无耦合!!!拖入项目可以直接使用,删除后项目也不需要做任何修改,直接build!以后再有新的交互需求你只需要按照上面的步骤创建插件完成功能并把结果返回给JS就可以了!不需要动框架!!
157-
158-
159-
### 3.自定义业务插件(JS侧)
160-
161-
3.1.以下为demo中自定义js插件代码,详情可参照demo:
162-
```js
163-
/**
164-
* 调用 Natvie Post 网络请求 方法
165-
* @param actionArgs 数据
166-
* @param callback 调用回调
167-
*/
168-
wk_bridge.prototype.nativePost = function (actionArgs, successCallback, failCallback) {
169-
var fetchConfig = bridgeConfig.fetch_id;
170-
var service = fetchConfig.service;
171-
var action = fetchConfig.action.action_post;
172-
window.WKJSBridge.callNative(service, action, actionArgs, successCallback, failCallback);
173-
};
174-
175-
/**
176-
* 调用 Natvie Get 网络请求 方法
177-
* @param actionArgs 数据
178-
* @param callback 调用回调
179-
*/
180-
wk_bridge.prototype.nativeGet = function (actionArgs, successCallback, failCallback) {
181-
var fetchConfig = bridgeConfig.fetch_id;
182-
var service = fetchConfig.service;
183-
var action = fetchConfig.action.action_get;
184-
window.WKJSBridge.callNative(service, action, actionArgs, successCallback, failCallback);
185-
};
186-
```
187-
188-
3.2. JS调用Native
189-
index.html中引用<script type="text/javascript" src="WKJSBridge.js" ></script>
190-
191-
```js
192-
// 模拟h5使用native来发送post请求
193-
function pokePost() {
194-
//业务参数
195-
var command = {
196-
'method':'post',
197-
'url':'https:www.baidu.com'
198-
}
199-
window.wk_bridge.nativePost(command, function success(res) {
200-
document.getElementById("returnValue").value = res.result;
201-
}, function fail(res) {
202-
document.getElementById("returnValue").value = res.result;
203-
});
204-
}
205-
206-
// 模拟h5使用native来发送get请求
207-
function pokeGet() {
208-
//业务参数
209-
var command = {
210-
'method':'get',
211-
'url':'https:www.baidu.com'
212-
}
213-
window.wk_bridge.nativeGet(command, function success(res) {
214-
document.getElementById("returnValue").value = res.result;
215-
}, function fail(res) {
216-
document.getElementById("returnValue").value = res.result;
217-
});
218-
}
51+
#import "WKJavaScriptBridge.h"
21952
```
22053

221-
`command`为想要传递的参数。
222-
`nativePost`为第一步自定义的js插件。
223-
`pokeGet`为第一步自定义的另一个插件,
22454

225-
3.3. 详细使用参照Demo。
55+
## 用法
56+
- 1、:
22657

227-
### 4.一些针对WKWebView带来的Crash问题处理
228-
4.1 由于WKWebView在请求过程中用户可能退出界面销毁对象,当请求回调时由于接收处理对象不存在,造成Bad Access crash,所以可将WKProcessPool设为单例
22958
```objc
230-
static WKProcessPool *_sharedWKProcessPoolInstance = nil;
231-
static dispatch_once_t onceToken;
232-
dispatch_once(&onceToken, ^{
233-
_sharedWKProcessPoolInstance = [[WKProcessPool alloc] init];
234-
});
235-
self.processPool = _sharedWKProcessPoolInstance;
236-
237-
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
238-
configuration.processPool = self.processPool;
59+
//在创建WKWebView的地方调用此方法
60+
self.bridge = [WKJavaScriptBridge bindBridgeWithWebView:yourwebView];
23961
```
62+
- 2、:
24063
241-
4.2 解决window.alert() 时 completionHandler 没有被调用导致崩溃问题
242-
243-
```objc
244-
@property (nonatomic, assign, getter=loadFinished) BOOL isLoadFinished;
245-
```
246-
```objc
247-
- (void)viewDidLoad {
248-
[super viewDidLoad];
249-
self.isLoadFinished = NO;
250-
}
251-
```
252-
```objc
253-
- (void)viewDidAppear:(BOOL)animated {
254-
[super viewDidAppear:animated];
255-
self.isLoadFinished = YES;
256-
}
257-
```
25864
```objc
259-
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
260-
261-
if (!self.isLoadFinished) {
262-
completionHandler();
263-
return;
264-
}
265-
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:message preferredStyle:UIAlertControllerStyleAlert];
266-
[alertController addAction:[UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { completionHandler(); }]];
267-
if (self)
268-
[self presentViewController:alertController animated:YES completion:^{}];
269-
else
270-
completionHandler();
271-
}
65+
//开启白名单,默认关闭。若开启,插件需要进行注册`@WKRegisterWhiteList(你的模块类名)`,参照Demo。
66+
[self.bridge openWhiteList:YES];
27267
```
27368

274-
## 后续功能延伸:
275-
276-
1. JS侧插件化。(complete)
277-
2. 基于此引入离线包。
278-
3. 引入flutter。
279-
4. 构建小程序。
280-
5. other ...
281-
28269
## License
28370

28471
WKJavaScriptBridge is available under the Apache License 2.0. See the [LICENSE](https://github.com/GitWangKai/WKJavaScriptBridge/blob/master/LICENSE) file for more info.

0 commit comments

Comments
 (0)