YHInjectConfigManager.m
4.92 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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
//
// YHInjectJsCordovaManager.m
// YH_Explorer
//
// Created by 孙凯 on 2018/5/15.
//
#import "YHInjectConfigManager.h"
@implementation SchmeModel4wk
- (instancetype)copyWithZone:(NSZone *)zone {
SchmeModel4wk *model = [[SchmeModel4wk allocWithZone:zone] init];
model.className = self.className;
model.schemeName = self.schemeName;
return model;
}
@end
@interface YHInjectConfigManager()
//设置自定义 scheme 处理
@property (nonatomic,strong) NSArray <SchmeModel4wk *> *schemeArray;
@property (nonatomic,copy)NSString *jsCordova;
@end
@implementation YHInjectConfigManager
/**
* @abstract
* 返回初始化好的单例
*
* @return 返回的单例
*/
+ (instancetype)sharedInstance{
static YHInjectConfigManager *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[YHInjectConfigManager alloc] init];
});
return sharedInstance;
}
#pragma mark - Private
/**
* 动态注入Js
*
* @param resource js的名称
*/
- (BOOL)injectJavascript:(NSString *)resource webView:(UIWebView*)webView{
if(!self.jsCordova) {
NSString *jsPath = [[NSBundle mainBundle] pathForResource:resource ofType:@"js"];
self.jsCordova = [NSString stringWithContentsOfFile:jsPath encoding:NSUTF8StringEncoding error:NULL];
}
//用cordova.version判断cordova是否注入成功
NSString* jsCordovaVersion = [NSString stringWithFormat:@"cordova.version"];
NSString* res = [webView stringByEvaluatingJavaScriptFromString:jsCordovaVersion];
if (res != nil && res.length > 0) {
return TRUE;
}
NSLog(@"injectJavascript uiwebview");
//注入cordova js 代码
[webView stringByEvaluatingJavaScriptFromString:self.jsCordova];
//再次判定是否已经注入
res = [webView stringByEvaluatingJavaScriptFromString:jsCordovaVersion];
if (res != nil && res.length > 0) {
return TRUE;
}
return FALSE;
}
/**
@brief 循环注入直到成功
@since 1.0.2
*/
- (void)cycleInject:(UIWebView*)webView {
BOOL bSuc = NO;
// 向网页中注入cordova
bSuc = [self injectJavascript:@"cordova" webView:webView];
if (!bSuc) {
__weak typeof(self) weakSelf = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[weakSelf cycleInject:webView];
});
}
}
- (void)cycleInjectWKWebView:(WKWebView *)webView
{
if(!self.jsCordova) {
NSString *jsPath = [[NSBundle mainBundle] pathForResource:@"cordova" ofType:@"js"];
self.jsCordova = [NSString stringWithContentsOfFile:jsPath encoding:NSUTF8StringEncoding error:NULL];
}
if (self.jsCordova.length == 0) {
return;
}
WKUserContentController *userContentController = webView.configuration.userContentController;
NSMutableArray<WKUserScript *> *array = [userContentController.userScripts mutableCopy];
WKUserScript *injectUserScript = nil;
for (WKUserScript *wkUScript in array) {
if ([wkUScript.source isEqual:self.jsCordova]) {
injectUserScript = wkUScript;
break;
}
}
if (!injectUserScript) {
injectUserScript = [[WKUserScript alloc] initWithSource:self.jsCordova injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
[userContentController addUserScript:injectUserScript];
NSLog(@"injectJavascript wkwebview success");
}
}
- (void)mockLocalURLResource:(NSArray <SchmeModel4wk *> *)array {
self.schemeArray = [array filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(SchmeModel4wk * _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
if ([evaluatedObject isKindOfClass:[SchmeModel4wk class]]
&& NSClassFromString(evaluatedObject.className)) {
return YES;
} else {
return NO;
}
}]];
}
- (void)unMockLocalURLResource {
@synchronized (self.schemeArray) {
if (self.schemeArray.count > 0) {
self.schemeArray = [NSArray array];
}
}
}
- (void)registerURLSchemeHandler:(WKWebViewConfiguration *)config {
if (self.modifyWKConfig) {
config.allowsInlineMediaPlayback = self.modifyWKConfig.allowsInlineMediaPlayback;
}
NSArray *resultArray = nil;
@synchronized (self.schemeArray) {
resultArray = [self.schemeArray copy];
}
for (SchmeModel4wk *item in resultArray) {
if (item.className.length > 0 && item.schemeName.length > 0) {
Class class = NSClassFromString(item.className);
if (class) {
if (@available(iOS 11.0, *)) {
[config setURLSchemeHandler:[class new] forURLScheme:item.schemeName];
} else {
// Fallback on earlier versions
}
}
}
}
}
@end