Repository navigation
Expand file tree
/
Copy pathWKWebViewHandleFactory.m
More file actions
executable file
·135 lines (114 loc) · 4.13 KB
/
Copy pathWKWebViewHandleFactory.m
File metadata and controls
executable file
·135 lines (114 loc) · 4.13 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
129
130
131
132
133
134
135
//
// WKWebViewHandleFactory.m
// Hybrid-framework
//
// Created by 王凯 on 2018/12/7.
// Copyright © 2018 王凯. All rights reserved.
//
#import "WKWebViewHandleFactory.h"
#import "WKMsgCommand.h"
#import "WKWebViewEngine.h"
#import <objc/message.h>
static const NSInteger JSON_SIZE_FOR_MAIN_THREAD = 4 * 1024; // Chosen arbitrarily.
@implementation WKWebViewHandleFactory {
__weak WKWebViewEngine *_webViewEngine;
NSDictionary *_commandDictionary;
}
- (instancetype)initWithWebViewEngine:(WKWebViewEngine *)webViewEngine {
if (self = [super init]) {
_webViewEngine = webViewEngine;
_commandDictionary = [NSDictionary dictionary];
}
return self;
}
- (void)handleMsgCommand:(NSString *)arguments {
[self handleCommand:arguments];
}
#pragma mark - handle
- (void)handleCommand:(NSString *)commandJson {
if (commandJson.length > 0) {
[self fetchCommands:commandJson];
[self executePending];
}
}
- (void)fetchCommands:(NSString *)command {
if ([command length] < JSON_SIZE_FOR_MAIN_THREAD) {
_commandDictionary = [self JSONObject:command];
} else {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^() {
self->_commandDictionary = [self JSONObject:command];
[self performSelectorOnMainThread:@selector(executePending) withObject:nil waitUntilDone:NO];
});
}
}
- (void)executePending {
if (_commandDictionary.allKeys.count > 0) {
WKMsgCommand *msgCommand = [WKMsgCommand commandFromJson:_commandDictionary];
#ifdef DEBUG
NSLog(@"Exec(%@): Calling %@.%@", msgCommand.callbackId, msgCommand.className, msgCommand.methodName);
#endif
if (![self execute:msgCommand]) {
#ifdef DEBUG
NSString *commandJson = [NSString stringWithFormat:@"%@",_commandDictionary];
static NSUInteger maxLogLength = 1024;
NSString *commandString = ([commandJson length] > maxLogLength) ?
[NSString stringWithFormat : @"%@[...]", [commandJson substringToIndex:maxLogLength]] :
commandJson;
NSLog(@"FAILED pluginJSON = %@", commandString);
#endif
}
}
}
- (BOOL)execute:(WKMsgCommand *)command {
if (command.className == nil || command.methodName == nil) {
#ifdef DEBUG
NSLog(@"ERROR: Classname and/or methodName not found for command.");
#endif
return NO;
}
BOOL retVal = YES;
double started = [[NSDate date] timeIntervalSince1970] * 1000.0;
WKBasePlugin *instance = [_webViewEngine.commandDelegate getCommandInstance:command.className];
if (!([instance isKindOfClass:[WKBasePlugin class]])) {
#ifdef DEBUG
NSLog(@"ERROR: Plugin '%@' not found, or is not a Plugin. Check your plugin mapping in config.xml.", command.className);
#endif
return NO;
}
NSString* methodName = [NSString stringWithFormat:@"%@:", command.methodName];
SEL normalSelector = NSSelectorFromString(methodName);
if ([instance respondsToSelector:normalSelector]) {
((void (*)(id, SEL, id))objc_msgSend)(instance, normalSelector, command);
} else {
#ifdef DEBUG
NSLog(@"ERROR: Method '%@' not defined in Plugin '%@'", methodName, command.className);
#endif
retVal = NO;
}
double elapsed = [[NSDate date] timeIntervalSince1970] * 1000.0 - started;
if (elapsed > 10) {
#ifdef DEBUG
NSLog(@"THREAD WARNING: ['%@'] took '%f' ms. Plugin should use a background thread.", command.className, elapsed);
#endif
}
return retVal;
}
- (void)dealloc {
_webViewEngine = nil;
}
- (id)JSONObject:(NSString *)json
{
@autoreleasepool {
NSError* error = nil;
id object = [NSJSONSerialization JSONObjectWithData:[json dataUsingEncoding:NSUTF8StringEncoding]
options:NSJSONReadingMutableContainers
error:&error];
if (error != nil) {
#ifdef DEBUG
NSLog(@"NSString JSONObject error: %@, Malformed Data: %@", [error localizedDescription], self);
#endif
}
return object;
}
}
@end