简体   繁体   中英

Best practice: How to call Objective-C code from JavaScript

I've been looking for a way to call Objective-C code from some JavaScript in my UIWebView . A lot of topics has been created about this, and some of them are recommending the procedure done in the blog post UIWebView Secrets - Part3 - How to Properly Call ObjectiveC From Javascript , where UIWebViewDelegate methods are hacked to call native Objective-C code from. Is this still the best way to do this? It seems that PhoneGap has a way to do this, but I cannot find out how to. But if their procedure is equal to this, I cannot see why I should include their library just to do this.

Which procedure is currently best practice to do this?

Without any external framework we can do that.To achieve this like phone we have to use webView. For example, If you need to call an objective c function when a button is clicked in the webview.When the onclick of your button in the html page calls a javascript, just add an iFrame which will include the function name of the objective C function.

eg:

var iframe = document.createElement("IFRAME");
    iframe.setAttribute("src", "js-frame:" + functionName + ":" + callbackId);
    document.documentElement.appendChild(iframe);
    iframe.parentNode.removeChild(iframe);
    iframe = null

;

This iFrame can be accesed in your webView Delegate implemented in your ParentView of the webView, like-

- (BOOL)webView:(UIWebView *)webView2 
shouldStartLoadWithRequest:(NSURLRequest *)request 
 navigationType:(UIWebViewNavigationType)navigationType {

    NSString *requestString = [[request URL] absoluteString];




    if ([requestString hasPrefix:@"js-frame:"]) {

        NSArray *components = [requestString componentsSeparatedByString:@":"];

        NSString *function = (NSString*)[components objectAtIndex:1];
        int callbackId = [((NSString*)[components objectAtIndex:2]) intValue];

                                  stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        ;

        [self handleCall:function callbackId:callbackId];

        return NO;
    }

    return YES;
}

The handleCall will have to handle the invoking of your intended method having name "function"

There is no (public) API to do this other than using a custom URL scheme inside your JS code to invoke javascript.

Let's say you load the URL myproto://invokeMethodA in your JS code like so

window.location.href = "myproto://invokeMethodA";

you can intercept that load in UIWebView s delegate method

– webView:shouldStartLoadWithRequest:navigationType:

and do your stuff. Make sure you return NO to not actually perform the the request.

我最终使用了博客文章中推荐的NativeBridge插件。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM