forked from illusionspaces/WKJavaScriptBridge
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWKWebViewEngine.m
More file actions
executable file
·128 lines (102 loc) · 4.14 KB
/
Copy pathWKWebViewEngine.m
File metadata and controls
executable file
·128 lines (102 loc) · 4.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//
// WKWebViewEngine.m
// Hybrid-framework
//
// Created by 王凯 on 2018/12/5.
// Copyright © 2018 王凯. All rights reserved.
//
#import "WKWebViewEngine.h"
#import "WKWebViewDelegate.h"
#import "WKCommandImpl.h"
@interface WKWebViewEngine ()<WKScriptMessageHandler, WKJavaScriptBridgeProtocol>
@property (nonatomic, strong) WKWebViewDelegate *WKWebViewDelegate;
@property (nonatomic, strong) WKWebPluginAnnotation *webPluginAnnotation;
@property (nonatomic, strong) WKWebViewHandleFactory *webViewhandleFactory;
@property (nonatomic, strong) NSMutableDictionary *pluginsMap;
@property (nonatomic, weak, readwrite) WKWebView *webView;
@property (nonatomic, weak, readwrite) NSObject <WKNavigationDelegate>*webViewDelegate;
@end
@implementation WKWebViewEngine
#pragma mark - public
+ (instancetype)bindBridgeWithWebView:(WKWebView *)webView withDelegate:(NSObject <WKNavigationDelegate>*)webViewDelegate {
return [self bridge:webView delegate:webViewDelegate];
}
#pragma mark - privite
+ (instancetype)bridge:(WKWebView *)webView delegate:(NSObject <WKNavigationDelegate>*)webViewDelegate {
WKWebViewEngine *bridge = [[WKWebViewEngine alloc] init];
if ([webView isKindOfClass:[WKWebView class]]) {
bridge.webViewDelegate = webViewDelegate;
bridge.webView = webView;
[bridge setupInstance];
[bridge configWKWebView:webView];
[bridge setJavaScriptBridge:bridge];
[bridge loadStartupPlugin];
return bridge;
}
[NSException raise:@"BadWebViewType" format:@"Unknown web view type."];
return nil;
}
- (void)configWKWebView:(WKWebView *)webView {
webView.navigationDelegate = _WKWebViewDelegate;
webView.configuration.userContentController = [[WKUserContentController alloc] init];
[webView.configuration.userContentController addScriptMessageHandler:self name:@"WKJSBridge"];
}
- (void)setupInstance{
_webViewhandleFactory = [[WKWebViewHandleFactory alloc] initWithWebViewEngine:self];
_WKWebViewDelegate = [[WKWebViewDelegate alloc] initWithWebViewEngine:self];
_webPluginAnnotation = [[WKWebPluginAnnotation alloc] initWithWebViewEngine:self];
_pluginsMap = [NSMutableDictionary dictionary];
_commandDelegate = [[WKCommandImpl alloc] initWithWebViewEngine:self];
self.openWhiteList = YES;
}
- (void)loadStartupPlugin {
[_webPluginAnnotation getAllRegisterPluginName];
}
- (void)registerPlugin:(WKBasePlugin *)plugin {
if ([plugin respondsToSelector:@selector(setCommandDelegate:)]) {
[plugin setCommandDelegate:_commandDelegate];
}
}
- (void)setJavaScriptBridge:(id<WKJavaScriptBridgeProtocol>)bridge {
_bridge = bridge;
}
#pragma mark - WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
if ([message.body isKindOfClass:[NSString class]]) {
[_webViewhandleFactory handleMsgCommand:message.body];
}
}
#pragma mark - WKJavaScriptBridgeProtocol
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^)(id , NSError *))completionHandler {
[self.webView evaluateJavaScript:javaScriptString completionHandler:^(id obj, NSError * _Nullable error) {
if (completionHandler) {
completionHandler(obj, error);
}
}];
}
- (void)setupPluginName:(NSString *)pluginName {
[self.pluginsMap setValue:pluginName forKey:[pluginName lowercaseString]];
}
- (id)getCommandInstance:(NSString*)pluginName {
NSString* className = [self.pluginsMap objectForKey:[pluginName lowercaseString]];
if (className == nil && self.isOpenWhiteList) {
#ifdef DEBUG
NSLog(@"(pluginName: (%@) does not register on the whitelist.", pluginName);
#endif
return nil;
}
id obj = [[NSClassFromString(pluginName) alloc] initWithWebViewEngine:self];
if (obj != nil) {
[self registerPlugin:obj];
}else {
#ifdef DEBUG
NSLog(@"(pluginName: (%@) does not exist.", pluginName);
#endif
}
return obj;
}
#pragma mark - dealloc
- (void)dealloc {
[self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"WKJSBridge"];
}
@end