UIWebView
Objective-C 调用 JavaScript
在使用UIWebView时,可以使用stringByEvaluatingJavaScriptFromString:方法来执行JavaScript代码。
示例代码:
NSString *result = [webView stringByEvaluatingJavaScriptFromString:@"returnFunction()"]; NSLog(@"JavaScript返回值: %@", result);
JavaScript 调用 Objective-C
通过自定义URL scheme实现。
使用webView的一个返回BOOL类型的监听网页的代理:shouldStartLoadWithRequest,在JS中,window.location.href = “hhh://callback”
在监听中监听头,然后把后面的string截取出来,用SEL变为函数名,然后调用
当在JavaScript中需要调用Objective-C代码时,可以通过改变window.location来触发Objective-C中的代理方法。
示例代码:
在Objective-C中,你可以在UIWebViewDelegate的webView:shouldStartLoadWithRequest:navigationType:方法中捕获这些请求:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { NSURL *URL = [request URL]; if ([[URL scheme] isEqualToString:@"hhh"]) { NSString *functionName = [URL host]; // 获取"callback" SEL selector = NSSelectorFromString([functionName stringByAppendingString:@":"]); if ([self respondsToSelector:selector]) { [self performSelector:selector withObject:nil afterDelay:0]; } return NO; } return YES; }
在JavaScript中,你可以这样触发Objective-C代码:
window.location.href = "hhh://callback";
建议使用更安全的方式
虽然上述方法可行,但自定义URL scheme方法可能导致安全问题,例如,可能会被恶意利用执行未授权的方法。因此,推荐使用更安全和现代的方法如WKWebView的WKScriptMessageHandler进行Native和JavaScript的交互。
注意:UIWebView已经被苹果于弃用,使用会造成审核不通过,推荐使用WKWebView
WKWebView
1. JavaScriptCore
JavaScriptCore是一个JavaScript引擎,提供了与JavaScript上下文(context)的接口,可以用来执行JavaScript代码和访问JavaScript对象。JavaScriptCore封装了一些基础的JavaScript对象,如Date、Array等,并允许你定义自己的对象和函数。
原生调用H5
在Objective-C代码中执行你需要的JavaScript代码。
示例代码:
JSContext *context = [[JSContext alloc] init]; // 执行JavaScript [context evaluateScript:@"your javascript code here"];
H5调用原生
在Objective-C中,可以通过context[@"functionName"]来注册一个可以被JavaScript调用的方法。
示例代码:
JSContext *context = [[JSContext alloc] init]; // 定义Objective-C block context[@"log"] = ^(NSString *msg) { NSLog(@"JS: %@", msg); };
然后在你的JavaScript代码中调用该方法:
log('Hello from JavaScript');
2. evaluateJavaScript和WKScriptMessageHandler
evaluate:评价,评估,估值
evaluateJavaScript:实现原生调用H5
使用WKWebView的evaluateJavaScript方法调用JavaScript代码,并从中获取结果。
示例代码:
在Objective-C中通过WKWebView调用JavaScript:
#import// 假设self.webView是你的WKWebView实例 WKWebView *webView = [[WKWebView alloc] init]; // JavaScript代码字符串 NSString *script = @"document.title"; // 执行JavaScript [webView evaluateJavaScript:script completionHandler:^(id _Nullable result, NSError * _Nullable error) { if (error) { NSLog(@"JavaScript执行错误: %@", error); return; } NSLog(@"页面标题: %@", result); }];
WKScriptMessageHandler:实现H5调用原生
WKWebView提供了更现代和功能更强大的接口来与JavaScript交互。evaluateJavaScript:completionHandler:方法可以执行JavaScript代码,并通过回调接收结果。你也可以使用WKScriptMessageHandler创建一个消息处理器,当JavaScript通过window.webkit.messageHandlers.YourHandler.postMessage(data)发送消息时,你可以在Objective-C的userContentController:didReceiveScriptMessage:方法中接收到。
首先在Objective-C中创建消息处理器:
// 在didFinishNavigation代理方法中添加JS调用OC的方法 - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {// 注册一个name为hello的js方法 [webView.configuration.userContentController addScriptMessageHandler:self name:@"hello"]; } //实现WKScriptMessageHandler此代理,然后在网页端通过window.webkit.messageHandlers.hello.postMessage({body: 'test'});即可调用 - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { NSLog(@"body: %@", message.body); }
以上就是使用
evaluateJavaScript 来实现原生调用H5
WKScriptMessageHandler 来实现H5调用原生
3. WKWebViewJavascriptBridge
WKWebViewJavascriptBridge是一个流行的开源库,用于在iOS应用中的WKWebView和HTML页面之间进行JavaScript与Objective-C或Swift代码的交互。它提供了一个简化的接口来发送消息和调用函数,使得原生代码和Web代码之间的通信更加便捷。
WKWebViewJavascriptBridge不完全属于之前提到的三种方法,它实际上是基于WKWebView的WKScriptMessageHandler封装而成的一个桥接工具,但它提供了更加高级和易用的API。
示例代码:
首先,项目中安装WKWebViewJavascriptBridge,通常通过CocoaPods安装:
pod 'WKWebViewJavascriptBridge', '~> 1.0.0'
然后,可以在你的Objective-C代码中这样使用它:
#import#import "WKWebViewJavascriptBridge.h" @interface ViewController () @property (nonatomic, strong) WKWebView *webView; @property (nonatomic, strong) WKWebViewJavascriptBridge *bridge; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 设置WebView self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds]; [self.view addSubview:self.webView]; // 初始化bridge self.bridge = [WKWebViewJavascriptBridge bridgeForWebView:self.webView]; [self.bridge setWebViewDelegate:self]; // 注册一个供JS调用的方法 [self.bridge registerHandler:@"testObjcCallback" handler:^(id data, WVJBResponseCallback responseCallback) { NSLog(@"testObjcCallback called: %@", data); responseCallback(@"Response from testObjcCallback"); }]; // 调用JS的方法 [self.bridge callHandler:@"testJavascriptHandler" data:@{ @"foo":@"before ready" }]; // 加载页面 NSURL *url = [NSURL URLWithString:@"https://example.com"]; [self.webView loadRequest:[NSURLRequest requestWithURL:url]]; } @end
在你的HTML/JavaScript中,你也需要设置对应的处理函数和调用:
// Connect to the Objective-C bridge document.addEventListener('DOMContentLoaded', function() { window.WebViewJavascriptBridge.registerHandler('testJavascriptHandler', function(data, responseCallback) { console.log("ObjC called testJavascriptHandler with", data); var responseData = { 'Javascript Says':'Right back atcha!' }; responseCallback(responseData); }); });
这样,就设置了一个双向通信的桥,可以从JavaScript调用Objective-C代码,也可以从Objective-C调用JavaScript代码。