diff --git a/README.md b/README.md index 62bb8dc24a4f913338f850081ac38cfd4d7e312b..f06daba9d22d55387122331541ab918eb2b9e0ba 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 073a7fa0b271b2403ce2d82ef7ca05d9954485e6..1c1fa6dfb7ee480359f2d2199442c940f9ebedd7 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 0000000000000000000000000000000000000000..c2b122be7eaa5fc018e190ceb01ad9d4d393afcf --- /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 Binary files /dev/null and b/iOS/DoraemonKit/Resource/Assets.xcassets/doraemon_js.imageset/doraemon_js@2x.png differ 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 Binary files /dev/null and b/iOS/DoraemonKit/Resource/Assets.xcassets/doraemon_js.imageset/doraemon_js@3x.png differ diff --git a/iOS/DoraemonKit/Resource/en.lproj/Doraemon.strings b/iOS/DoraemonKit/Resource/en.lproj/Doraemon.strings index 551b381840b63403fd5d6570b13c6105834dc0e2..31c9cab2e509d831d262e333d720d8803a38e6bf 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 bb63780e4d1bb960a4d118a8f934339112407b6f..280a1eaad84b922246b66871544af76973e76004 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 c2f1b7c3a0c7b2701c84db62f41e42bcfb74a7f8..12cb2976926af8c999f40b48cc3a364ad8f72f8d 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 04c4df35575f6c494d1409967b49bf736a4a0f68..2b861168d86b4a6c46715f5edae1f9118293a72b 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 392113aea4f8b4964df0e76486d6360913a536f5..4141e4a08dc952ff956606e981a6c4805e99e561 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 49af71a96de6070df3ee68e1670e34bd2f3da675..53a245b143ac5498dd8590bf077f2e8c77c08188 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 00e0bfdc11eb91d84d87b168b32a43a0d4097a41..959c737f84b3142231c55d5955d2a12b61ffa269 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 34c93a5568896f18974dde66bd26504e711a7ab4..149a7cfc99753212685bc41bf302ce0135565dba 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 0000000000000000000000000000000000000000..53300fd280cd842cf0ab63f9daa7c6b98d65eb6e --- /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 0000000000000000000000000000000000000000..adfae128c4435bf25ade31a81057630c6de71c06 --- /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 0000000000000000000000000000000000000000..8992227474c124cf68990772eea77317a4da1a67 --- /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 0000000000000000000000000000000000000000..1d7d4b5f6f503a2270ab8fc4441f239e10a26842 --- /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 0000000000000000000000000000000000000000..18be41c9101e1f472e4ebdb278b843c80369c93a --- /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 0000000000000000000000000000000000000000..a467651798cea75b6ed6db6a780a5973a81cfb8c --- /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 0000000000000000000000000000000000000000..d8ee39ffe1c7e4ad2970a15af72275c8c338eb54 --- /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 0000000000000000000000000000000000000000..5ea8daef57693edb450095901a3eb32e85193415 --- /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 27e6ea57336168e1d4a901ee2c19aa2c9479b013..c407e956821bb2d5a8a7927ddad122fc540f355a 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 78216a03ade3bf0da1074272d09a897bceb9a4e5..27908ceb7219098886416ba7f73fd919c93d3b1b 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 7574aee2fa7280717259fe13faf2ecd6ef599209..923cdb0fb73ba1fe58709c12187dfdf56f2adada 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 2a63aa6b9a8b0e2c437756eb19c1a2b6570f58e8..05df99296ad8c104c197415dbeb2c39afdb57ca5 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 caf14b709b97cea3401a2fc7bd61f1a0fda3d07b..99415d40a4389d4c3b2947b75d586d9fcf16b5ce 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