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

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

本文关键字:JavaScript 调用 Objective-C 代码 最佳      更新时间:2023-09-26

我一直在寻找一种方法,从我的UIWebView中的一些JavaScript调用Objective-C代码。关于这一点,已经创建了很多主题,其中一些主题推荐了博客文章UIWebView Secrets-Part3-How to Proporty Call ObjectiveC From Javascript中所做的过程,其中UIWebViewDelegate方法被黑客入侵,从中调用本机Objective-C代码。这仍然是最好的方法吗?PhoneGap似乎有办法做到这一点,但我不知道如何做到。但如果他们的程序与此相同,我不明白为什么我要包括他们的库来做到这一步。

目前最佳做法是采用哪种程序?

没有任何外部框架,我们就能做到这一点。为了实现这一点,我们必须使用webView。例如,如果在Web视图中单击按钮时需要调用目标c函数。当你在html页面中点击按钮调用javascript时,只需添加一个iFrame,其中将包括目标C函数的函数名

例如:

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

此iFrame可以在您的webView中访问,在您的webView的ParentView中实现代理,如-

- (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;
}

handleCall必须处理调用名为"function"的预期方法

除了在JS代码中使用自定义URL方案来调用javascript之外,没有(公共)API可以做到这一点。

假设你在JS代码中加载URL myproto://invokeMethodA,就像一样

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

您可以在UIWebView的委托方法中截获该负载

– webView:shouldStartLoadWithRequest:navigationType:

做你的事。请确保返回NO以不实际执行请求。

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