From ef0c2420bdd568c2574193dafa05a9a17f4349b7 Mon Sep 17 00:00:00 2001 From: moliya Date: Tue, 31 May 2022 21:55:23 +0800 Subject: [PATCH] =?UTF-8?q?feat(iOS):=20=E6=96=B0=E5=A2=9EJS=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=E6=8F=92=E4=BB=B6=20(#1023)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 新增JS脚本插件 * 优化页面切换效果 * update README Co-authored-by: carefree <946715806@qq.com> --- README.md | 3 +- README_EN.md | 1 + .../doraemon_js.imageset/Contents.json | 22 ++++ .../doraemon_js.imageset/doraemon_js@2x.png | Bin 0 -> 5574 bytes .../doraemon_js.imageset/doraemon_js@3x.png | Bin 0 -> 10224 bytes .../Resource/en.lproj/Doraemon.strings | 9 ++ .../Resource/zh-Hans.lproj/Doraemon.strings | 9 ++ .../Src/Core/Cache/DoraemonCacheManager.h | 6 ++ .../Src/Core/Cache/DoraemonCacheManager.m | 63 +++++++++++ .../Src/Core/Category/UIView+Doraemon.h | 2 + .../Src/Core/Category/UIView+Doraemon.m | 11 ++ .../Src/Core/Manager/DoraemonManager.h | 2 + .../Src/Core/Manager/DoraemonManager.m | 9 ++ .../DoraemonJavaScriptDetailViewController.h | 18 ++++ .../DoraemonJavaScriptDetailViewController.m | 62 +++++++++++ .../JavaScript/DoraemonJavaScriptPlugin.h | 17 +++ .../JavaScript/DoraemonJavaScriptPlugin.m | 19 ++++ .../DoraemonJavaScriptViewController.h | 16 +++ .../DoraemonJavaScriptViewController.m | 102 ++++++++++++++++++ .../Function/DoraemonJavaScriptManager.h | 22 ++++ .../Function/DoraemonJavaScriptManager.m | 89 +++++++++++++++ iOS/DoraemonKit/Src/Core/Util/DoraemonUtil.h | 2 + iOS/DoraemonKit/Src/Core/Util/DoraemonUtil.m | 12 +++ .../DoraemonMultiNetWorkSerivce.m | 4 +- .../DoraemonKitDemo/DoKitAppDelegate.m | 1 + iOS/DoraemonKitDemo/Podfile.lock | 23 ++-- 26 files changed, 509 insertions(+), 15 deletions(-) create mode 100644 iOS/DoraemonKit/Resource/Assets.xcassets/doraemon_js.imageset/Contents.json create mode 100644 iOS/DoraemonKit/Resource/Assets.xcassets/doraemon_js.imageset/doraemon_js@2x.png create mode 100644 iOS/DoraemonKit/Resource/Assets.xcassets/doraemon_js.imageset/doraemon_js@3x.png create mode 100644 iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptDetailViewController.h create mode 100644 iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptDetailViewController.m create mode 100644 iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptPlugin.h create mode 100644 iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptPlugin.m create mode 100644 iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptViewController.h create mode 100644 iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptViewController.m create mode 100644 iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/Function/DoraemonJavaScriptManager.h create mode 100644 iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/Function/DoraemonJavaScriptManager.m diff --git a/README.md b/README.md index 62bb8dc2..f06daba9 100644 --- a/README.md +++ b/README.md @@ -114,7 +114,8 @@ DoKit 是一个功能平台,能够让每一个 App 快速接入一些常用的 10. **【NSLog】** 把所有 NSLog 信息打印到UI界面,避免没有开发证书无法调试的尴尬; 11. **【Lumberjack】** 每一条 CocoaLumberjack 的日志信息,都在在 App 的界面中显示出来,再也不需要导出日志这么麻烦;(iOS独有) 12. **【DBView】** 通过网页方便快捷的操作应用内数据库,让数据库的调试变得非常优雅; -13. **【模拟弱网】** 限制网速,模拟弱网环境下App的运行情况。(android独有) +13. **【模拟弱网】** 限制网速,模拟弱网环境下App的运行情况;(android独有) +14. **【JS脚本】** 在指定WebView运行JS脚本。(iOS独有) ### 三、性能检测 diff --git a/README_EN.md b/README_EN.md index 073a7fa0..1c1fa6df 100644 --- a/README_EN.md +++ b/README_EN.md @@ -54,6 +54,7 @@ DoKit is rich in functions, easy to access, and easy to expand. Everyone is welc * Log:print all logs to the UI interface for easy viewing * UserDefaults(iOS): add, delete, and modify the NSUserDefaults file * DBView:perform more detailed operations on the DB file on the web +* JavaScript(iOS):execute scripts in the web view ### Performance Tools diff --git a/iOS/DoraemonKit/Resource/Assets.xcassets/doraemon_js.imageset/Contents.json b/iOS/DoraemonKit/Resource/Assets.xcassets/doraemon_js.imageset/Contents.json new file mode 100644 index 00000000..c2b122be --- /dev/null +++ b/iOS/DoraemonKit/Resource/Assets.xcassets/doraemon_js.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "doraemon_js@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "doraemon_js@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS/DoraemonKit/Resource/Assets.xcassets/doraemon_js.imageset/doraemon_js@2x.png b/iOS/DoraemonKit/Resource/Assets.xcassets/doraemon_js.imageset/doraemon_js@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0d8b43cf86c93b8ba225fb9df84c88af678d59bf GIT binary patch literal 5574 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 Hw2Js2Vg~u4 literal 0 HcmV?d00001 diff --git a/iOS/DoraemonKit/Resource/Assets.xcassets/doraemon_js.imageset/doraemon_js@3x.png b/iOS/DoraemonKit/Resource/Assets.xcassets/doraemon_js.imageset/doraemon_js@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..ac9665da0a5bea72e726f77b8b2aa0ff372cf235 GIT binary patch literal 10224 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 literal 0 HcmV?d00001 diff --git a/iOS/DoraemonKit/Resource/en.lproj/Doraemon.strings b/iOS/DoraemonKit/Resource/en.lproj/Doraemon.strings index 551b3818..31c9cab2 100644 --- a/iOS/DoraemonKit/Resource/en.lproj/Doraemon.strings +++ b/iOS/DoraemonKit/Resource/en.lproj/Doraemon.strings @@ -132,6 +132,15 @@ //UserDefaults + //JS脚本 + "JS脚本" = "JavaScript"; + "请选择WebView" = "Select WebView"; + "无可用的WebView" = "No Available WebView"; + "脚本列表" = "Script List"; + "脚本执行" = "Execute Script"; + "JS代码" = "JS Code"; + "脚本不能为空" = "Code can not be empty"; + //CocoaLumberjack "Lumberjack" = "Lumberjack"; "CocoaLumberjack日志记录" = "CocoaLumberjack"; diff --git a/iOS/DoraemonKit/Resource/zh-Hans.lproj/Doraemon.strings b/iOS/DoraemonKit/Resource/zh-Hans.lproj/Doraemon.strings index bb63780e..280a1eaa 100644 --- a/iOS/DoraemonKit/Resource/zh-Hans.lproj/Doraemon.strings +++ b/iOS/DoraemonKit/Resource/zh-Hans.lproj/Doraemon.strings @@ -132,6 +132,15 @@ //UserDefaults + //JS脚本 + "JS脚本" = "JavaScript"; + "请选择WebView" = "请选择WebView"; + "无可用的WebView" = "无可用的WebView"; + "脚本列表" = "脚本列表"; + "脚本执行" = "脚本执行"; + "JS代码" = "JS代码"; + "脚本不能为空" = "脚本不能为空"; + //CocoaLumberjack "Lumberjack" = "Lumberjack"; "CocoaLumberjack日志记录" = "CocoaLumberjack日志记录"; diff --git a/iOS/DoraemonKit/Src/Core/Cache/DoraemonCacheManager.h b/iOS/DoraemonKit/Src/Core/Cache/DoraemonCacheManager.h index c2f1b7c3..12cb2976 100644 --- a/iOS/DoraemonKit/Src/Core/Cache/DoraemonCacheManager.h +++ b/iOS/DoraemonKit/Src/Core/Cache/DoraemonCacheManager.h @@ -78,6 +78,12 @@ - (void)clearAllH5historicalRecord; - (void)clearH5historicalRecordWithText:(NSString *)text; +/// JS历史脚本 +- (NSArray *)jsHistoricalRecord; +- (NSString *)jsHistoricalRecordForKey:(NSString *)key; +- (void)saveJsHistoricalRecordWithText:(NSString *)text forKey:(NSString *)key; +- (void)clearJsHistoricalRecordWithKey:(NSString *)key; + /// 保存启动类 - (void)saveStartClass : (NSString *)startClass; - (NSString *)startClass; diff --git a/iOS/DoraemonKit/Src/Core/Cache/DoraemonCacheManager.m b/iOS/DoraemonKit/Src/Core/Cache/DoraemonCacheManager.m index 04c4df35..2b861168 100644 --- a/iOS/DoraemonKit/Src/Core/Cache/DoraemonCacheManager.m +++ b/iOS/DoraemonKit/Src/Core/Cache/DoraemonCacheManager.m @@ -23,6 +23,7 @@ static NSString * const kDoraemonNSLogKey = @"doraemon_nslog_key"; static NSString * const kDoraemonMethodUseTimeKey = @"doraemon_method_use_time_key"; static NSString * const kDoraemonLargeImageDetectionKey = @"doraemon_large_image_detection_key"; static NSString * const kDoraemonH5historicalRecord = @"doraemon_historical_record"; +static NSString * const kDoraemonJsHistoricalRecord = @"doraemon_js_historical_record"; static NSString * const kDoraemonStartTimeKey = @"doraemon_start_time_key"; static NSString * const kDoraemonStartClassKey = @"doraemon_start_class_key"; static NSString * const kDoraemonANRTrackKey = @"doraemon_anr_track_key"; @@ -265,6 +266,68 @@ static NSString * const kDoraemonHealthStartKey = @"doraemon_health_start_key"; [_defaults synchronize]; } +- (NSArray *)jsHistoricalRecord { + return [_defaults arrayForKey:kDoraemonJsHistoricalRecord]; +} + +- (NSString *)jsHistoricalRecordForKey:(NSString *)key { + NSArray *history = [self jsHistoricalRecord] ?: @[]; + for (NSDictionary *dict in history) { + //是否同名配置 + if ([[dict objectForKey:@"key"] isEqualToString:key]) { + return [dict objectForKey:@"value"]; + } + } + return nil; +} + +- (void)saveJsHistoricalRecordWithText:(NSString *)text forKey:(NSString *)key { + NSString *saveKey = [NSString stringWithFormat:@"%.0f", NSDate.date.timeIntervalSince1970]; + if (key.length > 0) { + saveKey = key; + } + NSMutableArray *list = [NSMutableArray array]; + BOOL matched = NO; + NSArray *history = [self jsHistoricalRecord] ?: @[]; + for (NSDictionary *dict in history) { + //是否同名配置 + if ([[dict objectForKey:@"key"] isEqualToString:saveKey]) { + [list addObject:@{ + @"key": saveKey, + @"value": text + }]; + matched = YES; + continue; + } + [list addObject:dict]; + } + if (!matched) { + [list insertObject:@{ + @"key": saveKey, + @"value": text + } atIndex:0]; + } + [_defaults setObject:list forKey:kDoraemonJsHistoricalRecord]; + [_defaults synchronize]; +} + +- (void)clearJsHistoricalRecordWithKey:(NSString *)key { + if (!key) { + return; + } + NSMutableArray *list = [NSMutableArray array]; + NSArray *history = [self jsHistoricalRecord] ?: @[]; + for (NSDictionary *dict in history) { + //是否同名配置 + if ([[dict objectForKey:@"key"] isEqualToString:key]) { + continue; + } + [list addObject:dict]; + } + [_defaults setObject:list forKey:kDoraemonJsHistoricalRecord]; + [_defaults synchronize]; +} + - (void)saveStartClass : (NSString *)startClass { [_defaults setObject:startClass forKey:kDoraemonStartClassKey]; [_defaults synchronize]; diff --git a/iOS/DoraemonKit/Src/Core/Category/UIView+Doraemon.h b/iOS/DoraemonKit/Src/Core/Category/UIView+Doraemon.h index 392113ae..4141e4a0 100644 --- a/iOS/DoraemonKit/Src/Core/Category/UIView+Doraemon.h +++ b/iOS/DoraemonKit/Src/Core/Category/UIView+Doraemon.h @@ -47,5 +47,7 @@ - (UIViewController *)doraemon_viewController; +- (NSArray *)doraemon_findViewsForClass:(Class)clazz; + @end diff --git a/iOS/DoraemonKit/Src/Core/Category/UIView+Doraemon.m b/iOS/DoraemonKit/Src/Core/Category/UIView+Doraemon.m index 49af71a9..53a245b1 100644 --- a/iOS/DoraemonKit/Src/Core/Category/UIView+Doraemon.m +++ b/iOS/DoraemonKit/Src/Core/Category/UIView+Doraemon.m @@ -124,4 +124,15 @@ return nil; } +- (NSArray *)doraemon_findViewsForClass:(Class)clazz { + NSMutableArray *result = [NSMutableArray array]; + for (UIView *subview in self.subviews) { + if ([subview isKindOfClass:clazz]) { + [result addObject:subview]; + } + [result addObjectsFromArray:[subview doraemon_findViewsForClass:clazz]]; + } + return result; +} + @end diff --git a/iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.h b/iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.h index 00e0bfdc..959c737f 100644 --- a/iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.h +++ b/iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.h @@ -48,6 +48,8 @@ typedef NS_ENUM(NSUInteger, DoraemonManagerPluginType) { DoraemonManagerPluginType_DoraemonDatabasePlugin, // NSUserDefaults工具 DoraemonManagerPluginType_DoraemonNSUserDefaultsPlugin, + // JS脚本 + DoraemonManagerPluginType_DoraemonJavaScriptPlugin, #pragma mark - 性能检测 // 帧率监控 diff --git a/iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.m b/iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.m index 34c93a55..149a7cfc 100644 --- a/iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.m +++ b/iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.m @@ -242,6 +242,7 @@ typedef void (^DoraemonPerformanceBlock)(NSDictionary *); #if DoraemonWithDatabase [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonDatabasePlugin]; #endif + [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonJavaScriptPlugin]; #pragma mark - 性能检测 [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonFPSPlugin]; @@ -570,6 +571,14 @@ typedef void (^DoraemonPerformanceBlock)(NSDictionary *); @{kAtModule:DoraemonLocalizedString(@"常用工具")}, @{kBuriedPoint:@"dokit_sdk_comm_ck_userdefault"} ], + @(DoraemonManagerPluginType_DoraemonJavaScriptPlugin) : @[ + @{kTitle:DoraemonLocalizedString(@"JS脚本")}, + @{kDesc:DoraemonLocalizedString(@"JS脚本")}, + @{kIcon:@"doraemon_js"}, + @{kPluginName:@"DoraemonJavaScriptPlugin"}, + @{kAtModule:DoraemonLocalizedString(@"常用工具")}, + @{kBuriedPoint:@"dokit_sdk_comm_ck_js"} + ], // 性能检测 @(DoraemonManagerPluginType_DoraemonFPSPlugin) : @[ diff --git a/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptDetailViewController.h b/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptDetailViewController.h new file mode 100644 index 00000000..53300fd2 --- /dev/null +++ b/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptDetailViewController.h @@ -0,0 +1,18 @@ +// +// DoraemonJavaScriptDetailViewController.h +// DoraemonKit +// +// Created by carefree on 2022/5/11. +// + +#import "DoraemonBaseViewController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface DoraemonJavaScriptDetailViewController : DoraemonBaseViewController + +@property (nonatomic, copy) NSString *key; + +@end + +NS_ASSUME_NONNULL_END diff --git a/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptDetailViewController.m b/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptDetailViewController.m new file mode 100644 index 00000000..adfae128 --- /dev/null +++ b/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptDetailViewController.m @@ -0,0 +1,62 @@ +// +// DoraemonJavaScriptDetailViewController.m +// DoraemonKit +// +// Created by carefree on 2022/5/11. +// + +#import "DoraemonJavaScriptDetailViewController.h" +#import "DoraemonKit.h" +#import "DoraemonDefine.h" +#import "DoraemonToastUtil.h" +#import "DoraemonCacheManager.h" +#import "DoraemonJavaScriptManager.h" + +@interface DoraemonJavaScriptDetailViewController () + +@property (nonatomic, weak) UITextView *textView; + +@end + +@implementation DoraemonJavaScriptDetailViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.title = DoraemonLocalizedString(@"脚本执行"); + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPlay target:self action:@selector(runScript)]; + UIEdgeInsets edge = UIEdgeInsetsMake(10, 10, 0, 10); + CGFloat width = self.view.bounds.size.width - edge.left - edge.right; + CGFloat height = self.view.bounds.size.height - edge.top - edge.bottom; + UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(edge.left, edge.top + IPHONE_NAVIGATIONBAR_HEIGHT, width, 30)]; + titleLabel.text = DoraemonLocalizedString(@"JS代码"); + + UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(edge.left, CGRectGetMaxY(titleLabel.frame) + edge.top, width, height - 200)]; + textView.layer.borderWidth = 1 / UIScreen.mainScreen.scale; + textView.layer.borderColor = [[UIColor lightGrayColor] CGColor]; + textView.layer.cornerRadius = 6; + textView.font = [UIFont systemFontOfSize:16]; + textView.textContainerInset = UIEdgeInsetsMake(8, 3, 8, 3); + + [self.view addSubview:titleLabel]; + [self.view addSubview:textView]; + self.textView = textView; + + if (self.key.length > 0) { + self.textView.text = [DoraemonCacheManager.sharedInstance jsHistoricalRecordForKey:self.key]; + } +} + +#pragma mark - Private +- (void)runScript { + NSString *value = self.textView.text; + if (value.length == 0) { + [DoraemonToastUtil showToastBlack:@"脚本不能为空" inView:self.view]; + return; + } + [DoraemonCacheManager.sharedInstance saveJsHistoricalRecordWithText:value forKey:self.key]; + [DoraemonManager.shareInstance hiddenHomeWindow]; + [DoraemonJavaScriptManager.shareInstance evalJavaScript:value]; +} + +@end diff --git a/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptPlugin.h b/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptPlugin.h new file mode 100644 index 00000000..89922274 --- /dev/null +++ b/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptPlugin.h @@ -0,0 +1,17 @@ +// +// DoraemonJavaScriptPlugin.h +// AFNetworking +// +// Created by carefree on 2022/5/11. +// + +#import +#import "DoraemonPluginProtocol.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface DoraemonJavaScriptPlugin : NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptPlugin.m b/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptPlugin.m new file mode 100644 index 00000000..1d7d4b5f --- /dev/null +++ b/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptPlugin.m @@ -0,0 +1,19 @@ +// +// DoraemonJavaScriptPlugin.m +// AFNetworking +// +// Created by carefree on 2022/5/11. +// + +#import "DoraemonJavaScriptPlugin.h" +#import "DoraemonJavaScriptManager.h" +#import "DoraemonHomeWindow.h" + +@implementation DoraemonJavaScriptPlugin + +- (void)pluginDidLoad { + [[DoraemonHomeWindow shareInstance] hide]; + [[DoraemonJavaScriptManager shareInstance] show]; +} + +@end diff --git a/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptViewController.h b/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptViewController.h new file mode 100644 index 00000000..18be41c9 --- /dev/null +++ b/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptViewController.h @@ -0,0 +1,16 @@ +// +// DoraemonJavaScriptViewController.h +// DoraemonKit +// +// Created by carefree on 2022/5/11. +// + +#import "DoraemonBaseViewController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface DoraemonJavaScriptViewController : DoraemonBaseViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptViewController.m b/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptViewController.m new file mode 100644 index 00000000..a4676517 --- /dev/null +++ b/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/DoraemonJavaScriptViewController.m @@ -0,0 +1,102 @@ +// +// DoraemonJavaScriptViewController.m +// DoraemonKit +// +// Created by carefree on 2022/5/11. +// + +#import "DoraemonJavaScriptViewController.h" +#import "DoraemonJavaScriptDetailViewController.h" +#import "DoraemonCacheManager.h" +#import "DoraemonDefine.h" + +@interface DoraemonJavaScriptViewController () + +@property (nonatomic, weak) UITableView *tableView; +@property (nonatomic, strong) NSMutableArray *items; + +@end + +@implementation DoraemonJavaScriptViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + self.title = DoraemonLocalizedString(@"脚本列表"); + + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addNewScript)]; + self.items = [NSMutableArray array]; + + UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; + tableView.delegate = self; + tableView.dataSource = self; + tableView.rowHeight = 100; + [self.view addSubview:tableView]; + self.tableView = tableView; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [self loadScriptData]; + [self.tableView reloadData]; +} + +#pragma mark - UITableViewDataSource +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return self.items.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; + if (!cell) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cell"]; + } + cell.textLabel.text = [self.items[indexPath.row] objectForKey:@"value"]; + cell.textLabel.numberOfLines = 4; + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + return cell; +} + +#pragma mark - UITableViewDelegate +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + DoraemonJavaScriptDetailViewController *detailVC = [[DoraemonJavaScriptDetailViewController alloc] init]; + detailVC.key = [self.items[indexPath.row] objectForKey:@"key"]; + [self.navigationController pushViewController:detailVC animated:YES]; +} + +- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { + return UITableViewCellEditingStyleDelete; +} + +- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { + if (editingStyle == UITableViewCellEditingStyleDelete) { + NSString *key = [self.items[indexPath.row] objectForKey:@"key"]; + [DoraemonCacheManager.sharedInstance clearJsHistoricalRecordWithKey:key]; + [self loadScriptData]; + [self.tableView reloadData]; + } +} + +#pragma mark - Private +- (void)addNewScript { + DoraemonJavaScriptDetailViewController *detailVC = [[DoraemonJavaScriptDetailViewController alloc] init]; + [self.navigationController pushViewController:detailVC animated:YES]; +} + +- (void)loadScriptData { + [self.items removeAllObjects]; + //读取历史数据 + NSArray *scriptItems = [DoraemonCacheManager.sharedInstance jsHistoricalRecord]; + if (!scriptItems) { + //添加内置脚本 + [DoraemonCacheManager.sharedInstance saveJsHistoricalRecordWithText:@"//安装vConsole\nimport('https://unpkg.com/vconsole').then(() => {\n new window.VConsole()\n})" forKey:@"vConsole"]; + [DoraemonCacheManager.sharedInstance saveJsHistoricalRecordWithText:@"//重新加载\nlocation.reload()" forKey:@"Reload"]; + [DoraemonCacheManager.sharedInstance saveJsHistoricalRecordWithText:@"//后退\nhistory.go(-1)" forKey:@"Back"]; + [DoraemonCacheManager.sharedInstance saveJsHistoricalRecordWithText:@"//前进\nhistory.go(1)" forKey:@"Forward"]; + + scriptItems = [DoraemonCacheManager.sharedInstance jsHistoricalRecord]; + } + [self.items addObjectsFromArray:scriptItems]; +} + +@end diff --git a/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/Function/DoraemonJavaScriptManager.h b/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/Function/DoraemonJavaScriptManager.h new file mode 100644 index 00000000..d8ee39ff --- /dev/null +++ b/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/Function/DoraemonJavaScriptManager.h @@ -0,0 +1,22 @@ +// +// DoraemonJavaScriptManager.h +// DoraemonKit +// +// Created by carefree on 2022/5/11. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface DoraemonJavaScriptManager : NSObject + ++ (DoraemonJavaScriptManager *)shareInstance; + +- (void)show; + +- (void)evalJavaScript:(NSString *)script; + +@end + +NS_ASSUME_NONNULL_END diff --git a/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/Function/DoraemonJavaScriptManager.m b/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/Function/DoraemonJavaScriptManager.m new file mode 100644 index 00000000..5ea8daef --- /dev/null +++ b/iOS/DoraemonKit/Src/Core/Plugin/Common/JavaScript/Function/DoraemonJavaScriptManager.m @@ -0,0 +1,89 @@ +// +// DoraemonJavaScriptManager.m +// DoraemonKit +// +// Created by carefree on 2022/5/11. +// + +#import "DoraemonJavaScriptManager.h" +#import +#import "DoraemonDefine.h" +#import "DoraemonHomeWindow.h" +#import "UIViewController+Doraemon.h" +#import "DoraemonJavaScriptViewController.h" + +@interface DoraemonJavaScriptManager () + +@property (nonatomic, weak) id webView; + +@end + +@implementation DoraemonJavaScriptManager + ++ (DoraemonJavaScriptManager *)shareInstance{ + static dispatch_once_t once; + static DoraemonJavaScriptManager *instance; + dispatch_once(&once, ^{ + instance = [[DoraemonJavaScriptManager alloc] init]; + }); + return instance; +} + +- (void)show { + NSArray *webViews = [DoraemonUtil getWebViews]; + + NSString *title = DoraemonLocalizedString(@"请选择WebView"); + UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:title preferredStyle:UIAlertControllerStyleActionSheet]; + for (NSInteger i = 0; i < webViews.count; i++) { + WKWebView *webView = webViews[i]; + NSString *actionTitle = webView.description; + UIAlertAction *action = [UIAlertAction actionWithTitle:actionTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { + [self selectWebView:webView]; + }]; + [alert addAction:action]; + } + if (webViews.count == 0) { + UIAlertAction *action = [UIAlertAction actionWithTitle:DoraemonLocalizedString(@"无可用的WebView") style:UIAlertActionStyleDestructive handler:nil]; + action.enabled = NO; + [alert addAction:action]; + } + if (webViews.count == 1) { + //只有一个,则跳过选择 + [self selectWebView:webViews.firstObject]; + return; + } + [alert addAction:[UIAlertAction actionWithTitle:DoraemonLocalizedString(@"取消") style:UIAlertActionStyleCancel handler:nil]]; + dispatch_async(dispatch_get_main_queue(), ^{ + [UIViewController.topViewControllerForKeyWindow presentViewController:alert animated:YES completion:nil]; + }); +} + +- (void)selectWebView:(id)webView { + self.webView = webView; + DoraemonJavaScriptViewController *vc = [[DoraemonJavaScriptViewController alloc] init]; + [DoraemonHomeWindow openPlugin:vc]; +} + +- (void)evalJavaScript:(NSString *)script { + id currentWebView = self.webView; + if (!currentWebView) { + return; + } + if ([currentWebView isKindOfClass:WKWebView.class]) { + WKWebView *webView = currentWebView; + [webView evaluateJavaScript:script completionHandler:^(id _Nullable result, NSError * _Nullable error) { + if (error) { + NSLog(@"js error: %@", error); + } + }]; + } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + if ([currentWebView isKindOfClass:UIWebView.class]) { + UIWebView *webView = currentWebView; + [webView stringByEvaluatingJavaScriptFromString:script]; + } +#pragma clang diagnostic pop +} + +@end diff --git a/iOS/DoraemonKit/Src/Core/Util/DoraemonUtil.h b/iOS/DoraemonKit/Src/Core/Util/DoraemonUtil.h index 27e6ea57..c407e956 100644 --- a/iOS/DoraemonKit/Src/Core/Util/DoraemonUtil.h +++ b/iOS/DoraemonKit/Src/Core/Util/DoraemonUtil.h @@ -55,6 +55,8 @@ + (UIWindow *)getKeyWindow; ++ (NSArray *)getWebViews; + + (void)openPlugin:(UIViewController *)vc __attribute__((deprecated("此方法已弃用,请使用[DoraemonHomeWindow openPlugin:vc];"))); + (UIViewController *)rootViewControllerForKeyWindow __attribute__((deprecated("此方法已弃用,请使用[UIViewController rootViewControllerForKeyWindow]"))); diff --git a/iOS/DoraemonKit/Src/Core/Util/DoraemonUtil.m b/iOS/DoraemonKit/Src/Core/Util/DoraemonUtil.m index 78216a03..27908ceb 100644 --- a/iOS/DoraemonKit/Src/Core/Util/DoraemonUtil.m +++ b/iOS/DoraemonKit/Src/Core/Util/DoraemonUtil.m @@ -7,6 +7,7 @@ // #import "DoraemonUtil.h" +#import #import "UIViewController+Doraemon.h" #import "DoraemonHomeWindow.h" #import "DoraemonAppInfoUtil.h" @@ -310,4 +311,15 @@ return keyWindow; } ++ (NSArray *)getWebViews { + NSMutableArray *webViews = [NSMutableArray array]; + // 查找当前window中的所有webView + [webViews addObjectsFromArray:[[self getKeyWindow] doraemon_findViewsForClass:WKWebView.class]]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [webViews addObjectsFromArray:[[self getKeyWindow] doraemon_findViewsForClass:UIWebView.class]]; +#pragma clang diagnostic pop + return webViews; +} + @end diff --git a/iOS/DoraemonKit/Src/MultiControl/Function/Mock/NetWorkSerivce/DoraemonMultiNetWorkSerivce.m b/iOS/DoraemonKit/Src/MultiControl/Function/Mock/NetWorkSerivce/DoraemonMultiNetWorkSerivce.m index 7574aee2..923cdb0f 100755 --- a/iOS/DoraemonKit/Src/MultiControl/Function/Mock/NetWorkSerivce/DoraemonMultiNetWorkSerivce.m +++ b/iOS/DoraemonKit/Src/MultiControl/Function/Mock/NetWorkSerivce/DoraemonMultiNetWorkSerivce.m @@ -37,7 +37,7 @@ NSString *url = @"http://www.dokit.cn/"; url = [NSString stringWithFormat:@"%@%@",url, api]; - [manager POST:url parameters:params success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) { + [manager POST:url parameters:params headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) { if (sus) { sus(responseObject); } @@ -77,7 +77,7 @@ url = [NSString stringWithFormat:@"%@%@",url, api]; - [manager GET:url parameters:params success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) { + [manager GET:url parameters:params headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) { if (sus) { sus(responseObject); } diff --git a/iOS/DoraemonKitDemo/DoraemonKitDemo/DoKitAppDelegate.m b/iOS/DoraemonKitDemo/DoraemonKitDemo/DoKitAppDelegate.m index 2a63aa6b..05df9929 100644 --- a/iOS/DoraemonKitDemo/DoraemonKitDemo/DoKitAppDelegate.m +++ b/iOS/DoraemonKitDemo/DoraemonKitDemo/DoKitAppDelegate.m @@ -65,6 +65,7 @@ [[DoraemonManager shareInstance] addH5DoorBlock:^(NSString *h5Url) { NSLog(@"使用自带容器打开H5链接: %@",h5Url); + }]; [[DoraemonManager shareInstance] addWebpHandleBlock:^UIImage * _Nullable(NSString * _Nonnull filePath) { diff --git a/iOS/DoraemonKitDemo/Podfile.lock b/iOS/DoraemonKitDemo/Podfile.lock index caf14b70..99415d40 100644 --- a/iOS/DoraemonKitDemo/Podfile.lock +++ b/iOS/DoraemonKitDemo/Podfile.lock @@ -21,32 +21,31 @@ PODS: - CocoaLumberjack (3.7.2): - CocoaLumberjack/Core (= 3.7.2) - CocoaLumberjack/Core (3.7.2) - - DoraemonKit/Core (3.0.8): + - DoraemonKit/Core (3.1.2): - AFNetworking - FMDB - GCDWebServer - GCDWebServer/WebDAV - GCDWebServer/WebUploader - - DoraemonKit/WithDatabase (3.0.8): + - DoraemonKit/WithDatabase (3.1.2): - DoraemonKit/Core - YYDebugDatabase - - DoraemonKit/WithGPS (3.0.8): + - DoraemonKit/WithGPS (3.1.2): - DoraemonKit/Core - - DoraemonKit/WithLoad (3.0.8): + - DoraemonKit/WithLoad (3.1.2): - DoraemonKit/Core - - DoraemonKit/WithLogger (3.0.8): + - DoraemonKit/WithLogger (3.1.2): - CocoaLumberjack - DoraemonKit/Core - - DoraemonKit/WithMLeaksFinder (3.0.8): + - DoraemonKit/WithMLeaksFinder (3.1.2): - DoraemonKit/Core - FBRetainCycleDetector - - DoraemonKit/WithMultiControl (3.0.8): - - AFNetworking + - DoraemonKit/WithMultiControl (3.1.2): - CocoaHTTPServer - CocoaLumberjack - DoraemonKit/Core - SocketRocket - - DoraemonKit/WithWeex (3.0.8): + - DoraemonKit/WithWeex (3.1.2): - DoraemonKit/Core - WeexSDK - WXDevtool @@ -140,12 +139,12 @@ SPEC CHECKSUMS: CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 CocoaHTTPServer: 5624681fc3473d43b18202f635f9b3abb013b530 CocoaLumberjack: b7e05132ff94f6ae4dfa9d5bce9141893a21d9da - DoraemonKit: 8df7d459f2af3da8e71a55fadf2d5d686551e79d + DoraemonKit: aa228d6cc263888f68dab6bd14507657397474c1 FBRetainCycleDetector: 46daef95c2dfa9be34b53087edf6a8f34e4c749c FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a GCDWebServer: 2c156a56c8226e2d5c0c3f208a3621ccffbe3ce4 JSONModel: 02ab723958366a3fd27da57ea2af2113658762e9 - libwebp: 9c174486ec18a564cf0ecea2adcc85d10968ff98 + libwebp: 946cb3063cea9236285f7e9a8505d806d30e07f3 Masonry: ff105a956abcd19a618b2028b121cb638d7a8e2f SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d SDWebImageWebPCoder: f56ab499e3ea57dfeb6c3187dce183b10e160db0 @@ -156,4 +155,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: eb4dd1e6c68fe5acfa519a16e30fff7583e1ea69 -COCOAPODS: 1.10.2 +COCOAPODS: 1.11.3 -- GitLab