简体   繁体   English

最佳实践:如何从JavaScript调用Objective-C代码

[英]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 . 我一直在寻找一种从UIWebView中的一些JavaScript调用Objective-C代码的方法。 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. 关于此的很多主题已经创建,其中一些主题推荐博客文章UIWebView Secrets-Part3-如何从Javascript正确调用ObjectiveC中完成的过程,该UIWebViewDelegate方法被黑以从中调用本机Objective-C代码。 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. 似乎PhoneGap可以执行此操作,但是我无法找到方法。 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. 没有任何外部框架,我们可以做到这一点。要实现像电话一样的功能,我们必须使用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. 例如,如果您需要在Web视图中单击按钮时调用目标c函数。当html页面中按钮的onclick调用javascript时,只需添加一个iFrame,其中将包含目标C函数的函数名称。

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- 可以在您的webView父视图中实现的webView委托中访问此iFrame,例如-

- (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" handleCall将必须处理名称为“ function”的预期方法的调用

There is no (public) API to do this other than using a custom URL scheme inside your JS code to invoke javascript. 除了在JS代码中使用自定义URL方案来调用javascript之外,没有(公共)API可以执行此操作。

Let's say you load the URL myproto://invokeMethodA in your JS code like so 假设您像这样在JS代码中加载URL myproto://invokeMethodA

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

you can intercept that load in UIWebView s delegate method 您可以在UIWebView的委托方法中拦截该负载

– webView:shouldStartLoadWithRequest:navigationType:

and do your stuff. 做你的事 Make sure you return NO to not actually perform the the request. 确保您返回NO而不实际执行请求。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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