Trigger objective C method from javascript using JavaScriptCore in iOS 7 in ViewControllers

后端 未结 1 1652
一向
一向 2020-12-13 16:44

I am loading a url in the webview which has below HTML and javascript function call. Now I am looking into when user touches submit button in webview it should call any meth

相关标签:
1条回答
  • 2020-12-13 17:08

    The Objective-C interface in the JavascriptCore framework introduced with iOS 7 permits calling Objective-C methods from Javascript. For a great intro to these features, check out the 2013 WWDC introduction "Integrating JavaScript into Native Apps" session on Apple's developer network: https://developer.apple.com/videos/wwdc/2013/?id=615

    It does have a brief section towards the end on WebView (MacOs only not iOS)

    The sample code below shows how to implement what you want for iOS.

    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0,40,320,320)];
        webView.delegate = self;
        [self.view addSubview:webView];
         NSString *pageSource = @"<!DOCTYPE html> <html> <head> </head> <body> <h1>My Mobile App</h1> <p>Please enter the Details</p> <form name=\"feedback\" method=\"post\" action=\"mailto:you@site.com\"> <!-- Form elements will go in here --> </form> <form name=\"inputform\"> <input type=\"button\" onClick=\"submitButton('My Test Parameter')\" value=\"submit\"> </form> </body> </html>";
        [webView loadHTMLString:pageSource baseURL:nil];
    }
    
    - (void)webViewDidFinishLoad:(UIWebView *)webView
    {
        JSContext *context =  [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; // Undocumented access
        context[@"submitButton"] = ^(NSString *param1) {
            [self yourObjectiveCMethod:param1];
        };
    }
    
    - (void)yourObjectiveCMethod:(NSString *)param1 {
        NSLog(@"User clicked submit. param1=%@", param1);
    }
    

    Things to note:

    • Accessing the JSContext of a UIWebView is undocumented. Two techniques are known (see Access the JavaScriptCore engine of a UIWebView). The first technique is used here.
    • You don't need to define the javascript function "submitButton" inside the page, you will define the function from Objective-C using the webView's JSContext
    • A page load in a webview causes its JSContext to get replaced, hence you should implement a delegate for the UIWebView and define your Objective-C callback in your implementation of the selector for -webViewDidFinishLoad:
    • I've assumed you will want to pass parameters to this callback, so I've shown a sample parameter. Although this is not covered in the video tutorial mentioned above (or the PDF equivalent), looking at JSValue.h shows that JavascriptCore offers built-in conversion between the following Objective-C and Javascript types:

    .

      Objective-C type  |   JavaScript type
    --------------------+---------------------
            nil         |     undefined
           NSNull       |        null
          NSString      |       string
          NSNumber      |   number, boolean
        NSDictionary    |   Object object
          NSArray       |    Array object
           NSDate       |     Date object
          NSBlock *     |   Function object *
             id **      |   Wrapper object **
           Class ***    | Constructor object ***
    
    * Instances of NSBlock with supported arguments types will be presented to
    JavaScript as a callable Function object. For more information on supported
    argument types see JSExport.h. If a JavaScript Function originating from an
    Objective-C block is converted back to an Objective-C object the block will
    be returned. All other JavaScript functions will be converted in the same
    manner as a JavaScript object of type Object.
    
    ** For Objective-C instances that do not derive from the set of types listed
    above, a wrapper object to provide a retaining handle to the Objective-C
    instance from JavaScript. For more information on these wrapper objects, see
    JSExport.h. When a JavaScript wrapper object is converted back to Objective-C
    the Objective-C instance being retained by the wrapper is returned.
    
    *** For Objective-C Class objects a constructor object containing exported
    class methods will be returned. See JSExport.h for more information on
    constructor objects.
    
    0 讨论(0)
提交回复
热议问题