Skip to content

Commit ef0c242

Browse files
moliyacarefree
and
carefree
authored
feat(iOS): 新增JS脚本插件 (#1023)
* 新增JS脚本插件 * 优化页面切换效果 * update README Co-authored-by: carefree <[email protected]>
1 parent edea679 commit ef0c242

26 files changed

+509
-15
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ DoKit 是一个功能平台,能够让每一个 App 快速接入一些常用的
114114
10. **【NSLog】** 把所有 NSLog 信息打印到UI界面,避免没有开发证书无法调试的尴尬;
115115
11. **【Lumberjack】** 每一条 CocoaLumberjack 的日志信息,都在在 App 的界面中显示出来,再也不需要导出日志这么麻烦;(iOS独有)
116116
12. **【DBView】** 通过网页方便快捷的操作应用内数据库,让数据库的调试变得非常优雅;
117-
13. **【模拟弱网】** 限制网速,模拟弱网环境下App的运行情况。(android独有)
117+
13. **【模拟弱网】** 限制网速,模拟弱网环境下App的运行情况;(android独有)
118+
14. **【JS脚本】** 在指定WebView运行JS脚本。(iOS独有)
118119

119120
### 三、性能检测
120121

README_EN.md

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ DoKit is rich in functions, easy to access, and easy to expand. Everyone is welc
5454
* Log:print all logs to the UI interface for easy viewing
5555
* UserDefaults(iOS): add, delete, and modify the NSUserDefaults file
5656
* DBView:perform more detailed operations on the DB file on the web
57+
* JavaScript(iOS):execute scripts in the web view
5758

5859

5960
### Performance Tools
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"images" : [
3+
{
4+
"idiom" : "universal",
5+
"scale" : "1x"
6+
},
7+
{
8+
"filename" : "[email protected]",
9+
"idiom" : "universal",
10+
"scale" : "2x"
11+
},
12+
{
13+
"filename" : "[email protected]",
14+
"idiom" : "universal",
15+
"scale" : "3x"
16+
}
17+
],
18+
"info" : {
19+
"author" : "xcode",
20+
"version" : 1
21+
}
22+
}
Loading
Loading

iOS/DoraemonKit/Resource/en.lproj/Doraemon.strings

+9
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,15 @@
132132

133133
//UserDefaults
134134

135+
//JS脚本
136+
"JS脚本" = "JavaScript";
137+
"请选择WebView" = "Select WebView";
138+
"无可用的WebView" = "No Available WebView";
139+
"脚本列表" = "Script List";
140+
"脚本执行" = "Execute Script";
141+
"JS代码" = "JS Code";
142+
"脚本不能为空" = "Code can not be empty";
143+
135144
//CocoaLumberjack
136145
"Lumberjack" = "Lumberjack";
137146
"CocoaLumberjack日志记录" = "CocoaLumberjack";

iOS/DoraemonKit/Resource/zh-Hans.lproj/Doraemon.strings

+9
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,15 @@
132132

133133
//UserDefaults
134134

135+
//JS脚本
136+
"JS脚本" = "JavaScript";
137+
"请选择WebView" = "请选择WebView";
138+
"无可用的WebView" = "无可用的WebView";
139+
"脚本列表" = "脚本列表";
140+
"脚本执行" = "脚本执行";
141+
"JS代码" = "JS代码";
142+
"脚本不能为空" = "脚本不能为空";
143+
135144
//CocoaLumberjack
136145
"Lumberjack" = "Lumberjack";
137146
"CocoaLumberjack日志记录" = "CocoaLumberjack日志记录";

iOS/DoraemonKit/Src/Core/Cache/DoraemonCacheManager.h

+6
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@
7878
- (void)clearAllH5historicalRecord;
7979
- (void)clearH5historicalRecordWithText:(NSString *)text;
8080

81+
/// JS历史脚本
82+
- (NSArray<NSDictionary *> *)jsHistoricalRecord;
83+
- (NSString *)jsHistoricalRecordForKey:(NSString *)key;
84+
- (void)saveJsHistoricalRecordWithText:(NSString *)text forKey:(NSString *)key;
85+
- (void)clearJsHistoricalRecordWithKey:(NSString *)key;
86+
8187
/// 保存启动类
8288
- (void)saveStartClass : (NSString *)startClass;
8389
- (NSString *)startClass;

iOS/DoraemonKit/Src/Core/Cache/DoraemonCacheManager.m

+63
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
static NSString * const kDoraemonMethodUseTimeKey = @"doraemon_method_use_time_key";
2424
static NSString * const kDoraemonLargeImageDetectionKey = @"doraemon_large_image_detection_key";
2525
static NSString * const kDoraemonH5historicalRecord = @"doraemon_historical_record";
26+
static NSString * const kDoraemonJsHistoricalRecord = @"doraemon_js_historical_record";
2627
static NSString * const kDoraemonStartTimeKey = @"doraemon_start_time_key";
2728
static NSString * const kDoraemonStartClassKey = @"doraemon_start_class_key";
2829
static NSString * const kDoraemonANRTrackKey = @"doraemon_anr_track_key";
@@ -265,6 +266,68 @@ - (void)clearH5historicalRecordWithText:(NSString *)text {
265266
[_defaults synchronize];
266267
}
267268

269+
- (NSArray<NSDictionary *> *)jsHistoricalRecord {
270+
return [_defaults arrayForKey:kDoraemonJsHistoricalRecord];
271+
}
272+
273+
- (NSString *)jsHistoricalRecordForKey:(NSString *)key {
274+
NSArray *history = [self jsHistoricalRecord] ?: @[];
275+
for (NSDictionary *dict in history) {
276+
//是否同名配置
277+
if ([[dict objectForKey:@"key"] isEqualToString:key]) {
278+
return [dict objectForKey:@"value"];
279+
}
280+
}
281+
return nil;
282+
}
283+
284+
- (void)saveJsHistoricalRecordWithText:(NSString *)text forKey:(NSString *)key {
285+
NSString *saveKey = [NSString stringWithFormat:@"%.0f", NSDate.date.timeIntervalSince1970];
286+
if (key.length > 0) {
287+
saveKey = key;
288+
}
289+
NSMutableArray *list = [NSMutableArray array];
290+
BOOL matched = NO;
291+
NSArray *history = [self jsHistoricalRecord] ?: @[];
292+
for (NSDictionary *dict in history) {
293+
//是否同名配置
294+
if ([[dict objectForKey:@"key"] isEqualToString:saveKey]) {
295+
[list addObject:@{
296+
@"key": saveKey,
297+
@"value": text
298+
}];
299+
matched = YES;
300+
continue;
301+
}
302+
[list addObject:dict];
303+
}
304+
if (!matched) {
305+
[list insertObject:@{
306+
@"key": saveKey,
307+
@"value": text
308+
} atIndex:0];
309+
}
310+
[_defaults setObject:list forKey:kDoraemonJsHistoricalRecord];
311+
[_defaults synchronize];
312+
}
313+
314+
- (void)clearJsHistoricalRecordWithKey:(NSString *)key {
315+
if (!key) {
316+
return;
317+
}
318+
NSMutableArray *list = [NSMutableArray array];
319+
NSArray *history = [self jsHistoricalRecord] ?: @[];
320+
for (NSDictionary *dict in history) {
321+
//是否同名配置
322+
if ([[dict objectForKey:@"key"] isEqualToString:key]) {
323+
continue;
324+
}
325+
[list addObject:dict];
326+
}
327+
[_defaults setObject:list forKey:kDoraemonJsHistoricalRecord];
328+
[_defaults synchronize];
329+
}
330+
268331
- (void)saveStartClass : (NSString *)startClass {
269332
[_defaults setObject:startClass forKey:kDoraemonStartClassKey];
270333
[_defaults synchronize];

iOS/DoraemonKit/Src/Core/Category/UIView+Doraemon.h

+2
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,7 @@
4747

4848
- (UIViewController *)doraemon_viewController;
4949

50+
- (NSArray *)doraemon_findViewsForClass:(Class)clazz;
51+
5052
@end
5153

iOS/DoraemonKit/Src/Core/Category/UIView+Doraemon.m

+11
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,15 @@ -(UIViewController *)doraemon_viewController{
124124
return nil;
125125
}
126126

127+
- (NSArray *)doraemon_findViewsForClass:(Class)clazz {
128+
NSMutableArray *result = [NSMutableArray array];
129+
for (UIView *subview in self.subviews) {
130+
if ([subview isKindOfClass:clazz]) {
131+
[result addObject:subview];
132+
}
133+
[result addObjectsFromArray:[subview doraemon_findViewsForClass:clazz]];
134+
}
135+
return result;
136+
}
137+
127138
@end

iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.h

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ typedef NS_ENUM(NSUInteger, DoraemonManagerPluginType) {
4848
DoraemonManagerPluginType_DoraemonDatabasePlugin,
4949
// NSUserDefaults工具
5050
DoraemonManagerPluginType_DoraemonNSUserDefaultsPlugin,
51+
// JS脚本
52+
DoraemonManagerPluginType_DoraemonJavaScriptPlugin,
5153

5254
#pragma mark - 性能检测
5355
// 帧率监控

iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.m

+9
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ - (void)initData{
242242
#if DoraemonWithDatabase
243243
[self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonDatabasePlugin];
244244
#endif
245+
[self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonJavaScriptPlugin];
245246

246247
#pragma mark - 性能检测
247248
[self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonFPSPlugin];
@@ -570,6 +571,14 @@ - (DoraemonManagerPluginTypeModel *)getDefaultPluginDataWithPluginType:(Doraemon
570571
@{kAtModule:DoraemonLocalizedString(@"常用工具")},
571572
@{kBuriedPoint:@"dokit_sdk_comm_ck_userdefault"}
572573
],
574+
@(DoraemonManagerPluginType_DoraemonJavaScriptPlugin) : @[
575+
@{kTitle:DoraemonLocalizedString(@"JS脚本")},
576+
@{kDesc:DoraemonLocalizedString(@"JS脚本")},
577+
@{kIcon:@"doraemon_js"},
578+
@{kPluginName:@"DoraemonJavaScriptPlugin"},
579+
@{kAtModule:DoraemonLocalizedString(@"常用工具")},
580+
@{kBuriedPoint:@"dokit_sdk_comm_ck_js"}
581+
],
573582

574583
// 性能检测
575584
@(DoraemonManagerPluginType_DoraemonFPSPlugin) : @[
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// DoraemonJavaScriptDetailViewController.h
3+
// DoraemonKit
4+
//
5+
// Created by carefree on 2022/5/11.
6+
//
7+
8+
#import "DoraemonBaseViewController.h"
9+
10+
NS_ASSUME_NONNULL_BEGIN
11+
12+
@interface DoraemonJavaScriptDetailViewController : DoraemonBaseViewController
13+
14+
@property (nonatomic, copy) NSString *key;
15+
16+
@end
17+
18+
NS_ASSUME_NONNULL_END
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//
2+
// DoraemonJavaScriptDetailViewController.m
3+
// DoraemonKit
4+
//
5+
// Created by carefree on 2022/5/11.
6+
//
7+
8+
#import "DoraemonJavaScriptDetailViewController.h"
9+
#import "DoraemonKit.h"
10+
#import "DoraemonDefine.h"
11+
#import "DoraemonToastUtil.h"
12+
#import "DoraemonCacheManager.h"
13+
#import "DoraemonJavaScriptManager.h"
14+
15+
@interface DoraemonJavaScriptDetailViewController ()
16+
17+
@property (nonatomic, weak) UITextView *textView;
18+
19+
@end
20+
21+
@implementation DoraemonJavaScriptDetailViewController
22+
23+
- (void)viewDidLoad {
24+
[super viewDidLoad];
25+
26+
self.title = DoraemonLocalizedString(@"脚本执行");
27+
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPlay target:self action:@selector(runScript)];
28+
UIEdgeInsets edge = UIEdgeInsetsMake(10, 10, 0, 10);
29+
CGFloat width = self.view.bounds.size.width - edge.left - edge.right;
30+
CGFloat height = self.view.bounds.size.height - edge.top - edge.bottom;
31+
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(edge.left, edge.top + IPHONE_NAVIGATIONBAR_HEIGHT, width, 30)];
32+
titleLabel.text = DoraemonLocalizedString(@"JS代码");
33+
34+
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(edge.left, CGRectGetMaxY(titleLabel.frame) + edge.top, width, height - 200)];
35+
textView.layer.borderWidth = 1 / UIScreen.mainScreen.scale;
36+
textView.layer.borderColor = [[UIColor lightGrayColor] CGColor];
37+
textView.layer.cornerRadius = 6;
38+
textView.font = [UIFont systemFontOfSize:16];
39+
textView.textContainerInset = UIEdgeInsetsMake(8, 3, 8, 3);
40+
41+
[self.view addSubview:titleLabel];
42+
[self.view addSubview:textView];
43+
self.textView = textView;
44+
45+
if (self.key.length > 0) {
46+
self.textView.text = [DoraemonCacheManager.sharedInstance jsHistoricalRecordForKey:self.key];
47+
}
48+
}
49+
50+
#pragma mark - Private
51+
- (void)runScript {
52+
NSString *value = self.textView.text;
53+
if (value.length == 0) {
54+
[DoraemonToastUtil showToastBlack:@"脚本不能为空" inView:self.view];
55+
return;
56+
}
57+
[DoraemonCacheManager.sharedInstance saveJsHistoricalRecordWithText:value forKey:self.key];
58+
[DoraemonManager.shareInstance hiddenHomeWindow];
59+
[DoraemonJavaScriptManager.shareInstance evalJavaScript:value];
60+
}
61+
62+
@end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//
2+
// DoraemonJavaScriptPlugin.h
3+
// AFNetworking
4+
//
5+
// Created by carefree on 2022/5/11.
6+
//
7+
8+
#import <Foundation/Foundation.h>
9+
#import "DoraemonPluginProtocol.h"
10+
11+
NS_ASSUME_NONNULL_BEGIN
12+
13+
@interface DoraemonJavaScriptPlugin : NSObject<DoraemonPluginProtocol>
14+
15+
@end
16+
17+
NS_ASSUME_NONNULL_END
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// DoraemonJavaScriptPlugin.m
3+
// AFNetworking
4+
//
5+
// Created by carefree on 2022/5/11.
6+
//
7+
8+
#import "DoraemonJavaScriptPlugin.h"
9+
#import "DoraemonJavaScriptManager.h"
10+
#import "DoraemonHomeWindow.h"
11+
12+
@implementation DoraemonJavaScriptPlugin
13+
14+
- (void)pluginDidLoad {
15+
[[DoraemonHomeWindow shareInstance] hide];
16+
[[DoraemonJavaScriptManager shareInstance] show];
17+
}
18+
19+
@end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//
2+
// DoraemonJavaScriptViewController.h
3+
// DoraemonKit
4+
//
5+
// Created by carefree on 2022/5/11.
6+
//
7+
8+
#import "DoraemonBaseViewController.h"
9+
10+
NS_ASSUME_NONNULL_BEGIN
11+
12+
@interface DoraemonJavaScriptViewController : DoraemonBaseViewController
13+
14+
@end
15+
16+
NS_ASSUME_NONNULL_END

0 commit comments

Comments
 (0)