How can my iPhone Objective-C code get notified of Javascript errors in a UIWebView?

后端 未结 10 2390
再見小時候
再見小時候 2020-11-29 16:31

I need to have my iPhone Objective-C code catch Javascript errors in a UIWebView. That includes uncaught exceptions, syntax errors when loading files, undefined variable re

相关标签:
10条回答
  • 2020-11-29 16:52

    First setup WebViewJavascriptBridge , then override console.error function.

    In javascript

        window.originConsoleError = console.error;
        console.error = (msg) => {
            window.originConsoleError(msg);
            bridge.callHandler("sendConsoleLogToNative", {
                action:action,
                message:message
            }, null)
        };
    

    In Objective-C

    [self.bridge registerHandler:@"sendConsoleLogToNative" handler:^(id data, WVJBResponseCallback responseCallback) {
        NSString *action = data[@"action"];
        NSString *msg = data[@"message"];
        if (isStringValid(action)){
            if ([@"console.error" isEqualToString:action]){
                NSLog(@"JS error :%@",msg);
            }
        }
    }];
    
    0 讨论(0)
  • 2020-11-29 16:53

    See exception handling in iOS7: http://www.bignerdranch.com/blog/javascriptcore-example/

    [context setExceptionHandler:^(JSContext *context, JSValue *value) {
        NSLog(@"%@", value);
    }];
    
    0 讨论(0)
  • 2020-11-29 16:53

    A simpler solution for some cases might be to just add Firebug Lite to the Web page.

    0 讨论(0)
  • 2020-11-29 17:02

    Straight Forward Way: Put this code on top of your controller/view that is using the UIWebView

    #ifdef DEBUG
    @interface DebugWebDelegate : NSObject
    @end
    @implementation DebugWebDelegate
    @class WebView;
    @class WebScriptCallFrame;
    @class WebFrame;
    - (void)webView:(WebView *)webView   exceptionWasRaised:(WebScriptCallFrame *)frame
           sourceId:(int)sid
               line:(int)lineno
        forWebFrame:(WebFrame *)webFrame
    {
        NSLog(@"NSDD: exception: sid=%d line=%d function=%@, caller=%@, exception=%@", 
              sid, lineno, [frame functionName], [frame caller], [frame exception]);
    }
    @end
    @interface DebugWebView : UIWebView
    id windowScriptObject;
    id privateWebView;
    @end
    @implementation DebugWebView
    - (void)webView:(id)sender didClearWindowObject:(id)windowObject forFrame:(WebFrame*)frame
    {
        [sender setScriptDebugDelegate:[[DebugWebDelegate alloc] init]];
    }
    @end
    #endif
    

    And then instantiate it like this:

    #ifdef DEBUG
            myWebview = [[DebugWebView alloc] initWithFrame:frame];
    #else
            myWebview = [[UIWebView alloc] initWithFrame:frame];
    #endif
    

    Using #ifdef DEBUG ensures that it doesn't go in the release build, but I would also recommend commenting it out when you're not using it since it has a performance impact. Credit goes to Robert Sanders and Prcela for the original code

    Also if using ARC you may need to add "-fno-objc-arc" to prevent some build errors.

    0 讨论(0)
提交回复
热议问题