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

后端 未结 10 2428
再見小時候
再見小時候 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:37

    I have now found one way using the script debugger hooks in WebView (note, NOT UIWebView). I first had to subclass UIWebView and add a method like this:

    - (void)webView:(id)webView windowScriptObjectAvailable:(id)newWindowScriptObject {
        // save these goodies
        windowScriptObject = newWindowScriptObject;
        privateWebView = webView;
    
        if (scriptDebuggingEnabled) {
            [webView setScriptDebugDelegate:[[YourScriptDebugDelegate alloc] init]];
        }
    }
    

    Next you should create a YourScriptDebugDelegate class that contains methods like these:

    // in YourScriptDebugDelegate
    
    - (void)webView:(WebView *)webView       didParseSource:(NSString *)source
     baseLineNumber:(unsigned)lineNumber
            fromURL:(NSURL *)url
           sourceId:(int)sid
        forWebFrame:(WebFrame *)webFrame
    {
        NSLog(@"NSDD: called didParseSource: sid=%d, url=%@", sid, url);
    }
    
    // some source failed to parse
    - (void)webView:(WebView *)webView  failedToParseSource:(NSString *)source
     baseLineNumber:(unsigned)lineNumber
            fromURL:(NSURL *)url
          withError:(NSError *)error
        forWebFrame:(WebFrame *)webFrame
    {
        NSLog(@"NSDD: called failedToParseSource: url=%@ line=%d error=%@\nsource=%@", url, lineNumber, error, source);
    }
    
    - (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]);
    }
    

    There is probably a large runtime impact for this, as the debug delegate can also supply methods to be called for entering and exiting a stack frame, and for executing each line of code.

    See http://www.koders.com/noncode/fid7DE7ECEB052C3531743728D41A233A951C79E0AE.aspx for the Objective-C++ definition of WebScriptDebugDelegate.

    Those other methods:

    // just entered a stack frame (i.e. called a function, or started global scope)
    - (void)webView:(WebView *)webView    didEnterCallFrame:(WebScriptCallFrame *)frame
          sourceId:(int)sid
              line:(int)lineno
       forWebFrame:(WebFrame *)webFrame;
    
    // about to execute some code
    - (void)webView:(WebView *)webView willExecuteStatement:(WebScriptCallFrame *)frame
          sourceId:(int)sid
              line:(int)lineno
       forWebFrame:(WebFrame *)webFrame;
    
    // about to leave a stack frame (i.e. return from a function)
    - (void)webView:(WebView *)webView   willLeaveCallFrame:(WebScriptCallFrame *)frame
          sourceId:(int)sid
              line:(int)lineno
       forWebFrame:(WebFrame *)webFrame;
    

    Note that this is all hidden away in a private framework, so don't try to put this in code you submit to the App Store, and be prepared for some hackery to get it to work.

提交回复
热议问题