
嘻道奇闻
- 文章199742
- 阅读14625734
iOS开发:OC调用JS方法的三种实现方案及示例代码
哎我说,刚入门iOS开发那会儿,你是不是也遇到过这种情况?明明照着教程写了WebView加载网页,可OC怎么就是调不动JS方法呢?别慌,今天咱们就来掰扯掰扯这个事儿——??Objective-C调用JavaScript的三大绝活儿??,保准你看完就能上手!
第一招:JavaScriptCore框架(系统自带)
这个可是苹果自家产的"瑞士军刀"。先说重点啊,??不需要WebView就能直接执行JS代码??,你说神不神奇?咱们举个栗子:
objective复制#import
// 创建JS执行环境 JSContext *context = [[JSContext alloc] init]; // 直接执行JS加法运算 JSValue *result = [context evaluateScript:@"1+2 * 3"]; NSLog(@"计算结果:%@", @([result toInt32])); // 输出7
不过要注意个坑:??JSContext是线程敏感的??,别在主线程之外瞎操作。个人觉得这招适合处理简单计算,要是遇到复杂交互嘛...咱们接着往下看。
第二招:WebView的stringByEvaluatingJavaScript(传统方法)
老iOSer应该都用过这招,虽然现在??UIWebView已经废弃??了,但原理还是得懂。咱们拿WKWebView举个栗子:
objective复制// 加载网页后调用 [_webView evaluateJavaScript:@"showAlert('老铁666')" completionHandler:^(id _Nullable response, NSError * _Nullable error) { if (!error) { NSLog(@"JS执行成功,返回值:%@", response); } else { NSLog(@"出幺蛾子了:%@", error.localizedDescription); } }];
划重点啊:??必须等网页加载完成才能调用??,不然就是对着空气喊话。有次我忘了等webViewDidFinishLoad回调,硬是debug了俩小时,说多了都是泪啊!
第三招:WebViewJavascriptBridge(第三方神器)
这个可是江湖人称"桥接小王子"的三方库,用起来那叫一个丝滑。先上配置代码:
objective复制// 初始化桥接 WKWebViewJavascriptBridge *bridge = [WKWebViewJavascriptBridge bridgeForWebView:_webView]; // 注册OC方法给JS调用 [bridge registerHandler:@"OC_Alert" handler:^(id data, WVJBResponseCallback responseCallback) { NSLog(@"收到JS消息:%@", data); responseCallback(@"已收到"); }]; // 调用JS方法 [bridge callHandler:@"JS_ShowToast" data:@{@"msg":@"双击666"}];
个人强烈安利这个方案!??自带错误回调机制??,还能双向传参。不过要注意版本兼容问题,上次用最新版发现API有变动,害得我连夜改代码...
三大方案怎么选?看这张对比表就懂了
对比项 | JavaScriptCore | WKWebView原生 | WebViewJavascriptBridge |
---|---|---|---|
依赖环境 | 系统自带 | 系统自带 | 需要手动集成 |
交互复杂度 | 简单 | 中等 | 复杂但稳定 |
跨线程通信 | 不支持 | 支持 | 支持 |
适合场景 | 纯计算场景 | 基础页面交互 | 企业级复杂交互 |
学习成本 | ★☆☆ | ★★☆ | ★★★ |
常见翻车现场实录
-
??为什么我的JS方法调用没反应???
八成是网页没加载完就急着调用了,记得在webViewDidFinishLoad回调里操作 -
??传参老是报类型错误咋整???
OC传字典给JS时记得转JSON字符串,反过来用NSJSONSerialization解析 -
??回调函数怎么死活不执行???
检查JS方法有没有正确返回Promise或执行responseCallback
个人踩坑心得
干了这么多年iOS开发,发现个真理:??能用系统API就别瞎折腾三方库??。不过要是项目赶时间,WebViewJavascriptBridge确实能救命。最近有个新趋势——??Flutter和ReactNative的兴起??,让原生WebView交互的需求少了很多,但老项目维护还是得会这些基本功。
最后唠叨一句:??别在子线程操作UI相关的方法??,血的教训啊!上次在后台线程调JS导致页面白屏,被测试妹子追着打了三条街。好了,今天的干货就倒这么多,剩下的就靠各位自己动手试试啦!