diff --git a/doric-android/doric/src/main/java/pub/doric/DoricNativeDriver.java b/doric-android/doric/src/main/java/pub/doric/DoricNativeDriver.java index 37a79ac6..c7b85aff 100644 --- a/doric-android/doric/src/main/java/pub/doric/DoricNativeDriver.java +++ b/doric-android/doric/src/main/java/pub/doric/DoricNativeDriver.java @@ -76,8 +76,8 @@ public class DoricNativeDriver implements IDoricDriver { try { return doricJSEngine.invokeDoricMethod(method, args); } catch (Exception e) { - doricJSEngine.onException(e); - doricJSEngine.onLog(Log.ERROR, String.format("invokeDoricMethod(%s,...),error is %s", method, e.getLocalizedMessage())); + doricJSEngine.getRegistry().onException(e); + doricJSEngine.getRegistry().onLog(Log.ERROR, String.format("invokeDoricMethod(%s,...),error is %s", method, e.getLocalizedMessage())); return new JSDecoder(null); } } @@ -106,8 +106,8 @@ public class DoricNativeDriver implements IDoricDriver { doricJSEngine.prepareContext(contextId, script, source); return true; } catch (Exception e) { - doricJSEngine.onException(e); - doricJSEngine.onLog(Log.ERROR, String.format("createContext %s error is %s", source, e.getLocalizedMessage())); + doricJSEngine.getRegistry().onException(e); + doricJSEngine.getRegistry().onLog(Log.ERROR, String.format("createContext %s error is %s", source, e.getLocalizedMessage())); return false; } } @@ -123,8 +123,8 @@ public class DoricNativeDriver implements IDoricDriver { doricJSEngine.destroyContext(contextId); return true; } catch (Exception e) { - doricJSEngine.onException(e); - doricJSEngine.onLog(Log.ERROR, String.format("destroyContext %s error is %s", contextId, e.getLocalizedMessage())); + doricJSEngine.getRegistry().onException(e); + doricJSEngine.getRegistry().onLog(Log.ERROR, String.format("destroyContext %s error is %s", contextId, e.getLocalizedMessage())); return false; } } diff --git a/doric-iOS/Pod/Classes/Doric.h b/doric-iOS/Pod/Classes/Doric.h index 487653b9..57b4bf3b 100644 --- a/doric-iOS/Pod/Classes/Doric.h +++ b/doric-iOS/Pod/Classes/Doric.h @@ -27,4 +27,5 @@ #import "DoricViewController.h" #import "DoricPromise.h" #import "DoricLibrary.h" -#import "DoricNativePlugin.h" \ No newline at end of file +#import "DoricNativePlugin.h" +#import "DoricMonitorProtocol.h" \ No newline at end of file diff --git a/doric-iOS/Pod/Classes/DoricDriver.m b/doric-iOS/Pod/Classes/DoricDriver.m index adc9f0aa..3e979dd6 100644 --- a/doric-iOS/Pod/Classes/DoricDriver.m +++ b/doric-iOS/Pod/Classes/DoricDriver.m @@ -78,6 +78,7 @@ + (instancetype)instance { [ret setupResult:jsValue]; } @catch (NSException *exception) { [ret setupError:exception]; + [self.jsExecutor.registry onException:exception]; } }); return ret; @@ -110,6 +111,7 @@ - (DoricAsyncResult *)invokeContextEntity:(NSString *)contextId method:(NSString [ret setupResult:jsValue]; } @catch (NSException *exception) { [ret setupError:exception]; + [self.jsExecutor.registry onException:exception]; } }); return ret; @@ -132,6 +134,7 @@ - (DoricAsyncResult *)invokeContextEntity:(NSString *)contextId method:(NSString [ret setupResult:jsValue]; } @catch (NSException *exception) { [ret setupError:exception]; + [self.jsExecutor.registry onException:exception]; } }); return ret; @@ -145,9 +148,10 @@ - (DoricAsyncResult *)createContext:(NSString *)contextId script:(NSString *)scr if (!self) return; @try { [self.jsExecutor prepareContext:contextId script:script source:source]; - [ret setupResult:[NSNumber numberWithBool:YES]]; + [ret setupResult:@YES]; } @catch (NSException *exception) { [ret setupError:exception]; + [self.jsExecutor.registry onException:exception]; } }); return ret; @@ -161,9 +165,10 @@ - (DoricAsyncResult *)destroyContext:(NSString *)contextId { if (!self) return; @try { [self.jsExecutor destroyContext:contextId]; - [ret setupResult:[NSNumber numberWithBool:YES]]; + [ret setupResult:@YES]; } @catch (NSException *exception) { [ret setupError:exception]; + [self.jsExecutor.registry onException:exception]; } }); return ret; diff --git a/doric-iOS/Pod/Classes/DoricMonitorProtocol.h b/doric-iOS/Pod/Classes/DoricMonitorProtocol.h new file mode 100644 index 00000000..964e2c2b --- /dev/null +++ b/doric-iOS/Pod/Classes/DoricMonitorProtocol.h @@ -0,0 +1,17 @@ +// +// Created by pengfei.zhou on 2020/1/10. +// + +#import + +typedef NS_ENUM(NSInteger, DoricLogType) { + DoricLogTypeDebug = 0, + DoricLogTypeWarning = 1, + DoricLogTypeError = 2, +}; + +@protocol DoricMonitorProtocol +- (void)onException:(NSException *)exception; + +- (void)onLog:(DoricLogType)type message:(NSString *)message; +@end \ No newline at end of file diff --git a/doric-iOS/Pod/Classes/DoricRegistry.h b/doric-iOS/Pod/Classes/DoricRegistry.h index 99ef328e..98f214db 100644 --- a/doric-iOS/Pod/Classes/DoricRegistry.h +++ b/doric-iOS/Pod/Classes/DoricRegistry.h @@ -21,11 +21,12 @@ // #import +#import "DoricMonitorProtocol.h" NS_ASSUME_NONNULL_BEGIN @class DoricLibrary; -@interface DoricRegistry : NSObject +@interface DoricRegistry : NSObject - (NSString *)acquireJSBundle:(NSString *)name; @@ -44,6 +45,8 @@ NS_ASSUME_NONNULL_BEGIN - (NSDictionary *)environmentVariables; +- (void)registerMonitor:(id )monitor; + + (void)register:(DoricLibrary *)library; @end diff --git a/doric-iOS/Pod/Classes/DoricRegistry.m b/doric-iOS/Pod/Classes/DoricRegistry.m index 99e84348..e50445d5 100644 --- a/doric-iOS/Pod/Classes/DoricRegistry.m +++ b/doric-iOS/Pod/Classes/DoricRegistry.m @@ -47,6 +47,7 @@ #import "DoricDraggableNode.h" #import "DoricLibrary.h" #import "DoricNotificationPlugin.h" +#import "DoricUtil.h" @interface DoricLibraries : NSObject @property(nonatomic, strong) NSMutableSet *libraries; @@ -73,12 +74,26 @@ + (instancetype)instance { @end +@interface DoricDefaultMonitor : NSObject +@end + +@implementation DoricDefaultMonitor +- (void)onException:(NSException *)exception { + DoricLog(@"DefaultMonitor - onException - %@", exception.reason); +} + +- (void)onLog:(DoricLogType)type message:(NSString *)message { + DoricLog(message); +} +@end + @interface DoricRegistry () @property(nonatomic, strong) NSMutableDictionary *bundles; @property(nonatomic, strong) NSMutableDictionary *plugins; @property(nonatomic, strong) NSMutableDictionary *nodes; @property(nonatomic, strong) NSMutableDictionary *envVariables; +@property(nonatomic, strong) NSMutableSet > *monitors; @end @implementation DoricRegistry @@ -97,6 +112,8 @@ - (instancetype)init { [DoricLibraries.instance.libraries enumerateObjectsUsingBlock:^(DoricLibrary *obj, BOOL *stop) { [obj load:self]; }]; + _monitors = [NSMutableSet new]; + [self registerMonitor:[DoricDefaultMonitor new]]; } return self; } @@ -161,4 +178,20 @@ - (void)setEnvironment:(NSString *)key variable:(id)value { - (NSDictionary *)environmentVariables { return self.envVariables; } + +- (void)registerMonitor:(id )monitor { + [self.monitors addObject:monitor]; +} + +- (void)onException:(NSException *)exception { + for (id monitor in self.monitors) { + [monitor onException:exception]; + } +} + +- (void)onLog:(DoricLogType)type message:(NSString *)message { + for (id monitor in self.monitors) { + [monitor onLog:type message:message]; + } +} @end diff --git a/doric-iOS/Pod/Classes/Engine/DoricJSEngine.m b/doric-iOS/Pod/Classes/Engine/DoricJSEngine.m index 3b6488d7..cf768fcb 100644 --- a/doric-iOS/Pod/Classes/Engine/DoricJSEngine.m +++ b/doric-iOS/Pod/Classes/Engine/DoricJSEngine.m @@ -70,7 +70,13 @@ - (void)initJSExecutor { [self.jsExecutor injectGlobalJSObject:INJECT_ENVIRONMENT obj:[envDic copy]]; [self.jsExecutor injectGlobalJSObject:INJECT_LOG obj:^(NSString *type, NSString *message) { - DoricLog(@"JS:%@", message); + if ([type isEqualToString:@"e"]) { + [self.registry onLog:DoricLogTypeError message:message]; + } else if ([type isEqualToString:@"w"]) { + [self.registry onLog:DoricLogTypeWarning message:message]; + } else { + [self.registry onLog:DoricLogTypeDebug message:message]; + } }]; [self.jsExecutor injectGlobalJSObject:INJECT_EMPTY obj:^() { @@ -80,14 +86,15 @@ - (void)initJSExecutor { if (!self) return NO; NSString *content = [self.registry acquireJSBundle:name]; if (!content) { - DoricLog(@"require js bundle:%@ is empty", name); + [self.registry onLog:DoricLogTypeError message:[NSString stringWithFormat:@"require js bundle:%@ is empty", name]]; return NO; } @try { [self.jsExecutor loadJSScript:[self packageModuleScript:name content:content] source:[@"Module://" stringByAppendingString:name]]; } @catch (NSException *e) { - DoricLog(@"require js bundle:%@ error,for %@", name, e.reason); + [self.registry onLog:DoricLogTypeError + message:[NSString stringWithFormat:@"require js bundle:%@ error,for %@", name, e.reason]]; } return YES; }]; @@ -119,11 +126,16 @@ - (void)initJSExecutor { } - (void)initDoricEnvironment { - [self loadBuiltinJS:DORIC_BUNDLE_SANDBOX]; - NSString *path = [DoricBundle() pathForResource:DORIC_BUNDLE_LIB ofType:@"js"]; - NSString *jsContent = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; - [self.jsExecutor loadJSScript:[self packageModuleScript:DORIC_MODULE_LIB content:jsContent] - source:[@"Module://" stringByAppendingString:DORIC_MODULE_LIB]]; + @try { + + [self loadBuiltinJS:DORIC_BUNDLE_SANDBOX]; + NSString *path = [DoricBundle() pathForResource:DORIC_BUNDLE_LIB ofType:@"js"]; + NSString *jsContent = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; + [self.jsExecutor loadJSScript:[self packageModuleScript:DORIC_MODULE_LIB content:jsContent] + source:[@"Module://" stringByAppendingString:DORIC_MODULE_LIB]]; + } @catch (NSException *exception) { + [self.registry onException:exception]; + } } - (void)loadBuiltinJS:(NSString *)fileName { @@ -184,7 +196,9 @@ - (void)callbackTimer:(NSTimer *)timer { @try { [self invokeDoricMethod:DORIC_TIMER_CALLBACK, timerId, nil]; } @catch (NSException *exception) { - DoricLog(@"Timer Callback error:%@", exception.reason); + [self.registry onException:exception]; + [self.registry onLog:DoricLogTypeError + message:[NSString stringWithFormat:@"Timer Callback error:%@", exception.reason]]; } if (![repeat boolValue]) { [self.timers removeObjectForKey:[timerId stringValue]]; diff --git a/doric-iOS/Pod/Classes/Extension/DoricBridgeExtension.m b/doric-iOS/Pod/Classes/Extension/DoricBridgeExtension.m index 3f3a2b38..51cd4278 100644 --- a/doric-iOS/Pod/Classes/Extension/DoricBridgeExtension.m +++ b/doric-iOS/Pod/Classes/Extension/DoricBridgeExtension.m @@ -87,6 +87,7 @@ - (id)findClass:(Class)clz target:(id)target context:(DoricContext *)context met [invocation invoke]; } @catch (NSException *exception) { DoricLog(@"CallNative Error:%@", exception.reason); + [context.driver.registry onException:exception]; } }; @@ -102,6 +103,8 @@ - (id)findClass:(Class)clz target:(id)target context:(DoricContext *)context met ret = [JSValue valueWithObject:[returnValue copy] inContext:[JSContext currentContext]]; } else { DoricLog(@"CallNative Error:%@", @"Must return object type"); + [context.driver.registry onLog:DoricLogTypeError + message:[NSString stringWithFormat:@"CallNative Error:%@", @"Must return object type"]]; ret = nil; } } diff --git a/doric-iOS/Pod/Classes/Plugin/DoricShaderPlugin.m b/doric-iOS/Pod/Classes/Plugin/DoricShaderPlugin.m index 62fe12f2..e397a15d 100644 --- a/doric-iOS/Pod/Classes/Plugin/DoricShaderPlugin.m +++ b/doric-iOS/Pod/Classes/Plugin/DoricShaderPlugin.m @@ -108,6 +108,7 @@ - (id)findClass:(Class)clz target:(id)target method:(NSString *)name promise:(Do [invocation invoke]; } @catch (NSException *exception) { DoricLog(@"CallNative Error:%@", exception.reason); + [self.doricContext.driver.registry onException:exception]; } }; dispatch_async(dispatch_get_main_queue(), ^{