博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UIWebView 与 JS 交互(1):Objective-C 调用 Javascript
阅读量:6648 次
发布时间:2019-06-25

本文共 2822 字,大约阅读时间需要 9 分钟。

众所周知,随着硬件水平的发展,HTML5 与原生 APP 性能差距不断缩小,正在互联网科技领域扮演者越来越重要的角色。作为一种能很大程度上节约成本的技术方案,通过 HTML5 及 JS 实现的跨平台技术也越来越成熟。

作为一名普通的 iOS 开发者,我们在项目中也会或多或少的用到一些 JS 代码,如何实现 JS 和 OC 之间的交互常常是我们会面临的一个问题。最近一段时间,笔者最近由于工作需要,研究了很多 iOS 下与 JS 交互的问题,接下来我会把这个过程中遇到的坑和积累的经验分享给大家。

第一个要说的就是如何在 OC 下调用 JS,这个很简单,想必大家都会不约而同的回答出,使用 UIWebView 的stringByEvaluatingJavaScriptFromString 方法。

接下来我从自己的实际经历聊一下如何使用stringByEvaluatingJavaScriptFromString调用javascript

1、 stringByEvaluatingJavaScriptFromString只能在主线程执行。

比如,假如你调用了下面这段代码:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);dispatch_async(queue, ^{    [webView stringByEvaluatingJavaScriptFromString:@"aaa"];});

程序就会崩溃,并打出下面的log:

崩溃产生的原因是你在主线程以外的线程调用了UIKit,系统在执行stringByEvaluatingJavaScriptFromString的时候调用了UIKit里的一些方法,所以不允许在主线程之外的线程去调用这个方法。

解决方法也有很多可以用

[webView performSelectorOnMainThread:]

或者

dispatch_sync(dispatch_get_main_queue(), ^{    [webView stringByEvaluatingJavaScriptFromString:@"aaa"];});

2、简单调用系统提供的javascript方法

对于一些简单的javascript系统方法,我们可以通过stringByEvaluatingJavaScriptFromString做一下简单的调用,并取得返回值。

- (void)webViewDidFinishLoad:(UIWebView *)webView{    NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];    NSLog(@"%@", title);}

3、在加载的html里插入代码,并执行

比如我用下面的代码插入了一个名叫alertTest的函数到javascript里实现在页面中显示alert的功能。

- (void)webViewDidFinishLoad:(UIWebView *)webView{        [webView stringByEvaluatingJavaScriptFromString:         @"var script = document.createElement('script');"         "script.type = 'text/javascript';"         "script.text = \"function alertTest(str) { "         "alert(str)"         "}\";"         "document.getElementsByTagName('head')[0].appendChild(script);"];         [webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"alertTest('%@');", @"test"]];}

值得注意的一点是

- (void)webViewDidFinishLoad:(UIWebView *)webView方法指的并不是webview完全加载完毕,而是指网页中一个iframe或frame加载完毕,也就是说假如网页里有多个frame,那么webViewDidFinishLoad会执行多次。这就会导致上面插入代码的方法会执行多次,stringByEvaluatingJavaScriptFromString执行JS是一笔不小的时间开销,所以我们应该尽量减少使用它去执行复杂的JS代码。

我使用了下面的方式检查是否已经插入并执行了这个函数,typeof alertTest检查了alertTest这个函数是否存在,若存在则不执行if里面的代码插入和代码执行语句。

- (void)webViewDidFinishLoad:(UIWebView *)webView{    BOOL isExist = [[webView stringByEvaluatingJavaScriptFromString:@"typeof alertTest == \'function\';"] isEqualToString:@"true"];    if (!isExist) {        [webView stringByEvaluatingJavaScriptFromString:         @"var script = document.createElement('script');"         "script.type = 'text/javascript';"         "script.text = \"function alertTest(str) { "         "alert(str)"         "}\";"         "document.getElementsByTagName('head')[0].appendChild(script);"];        [webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"alertTest('%@');", @"test"]];    }}

,监控网络请求及网络错误,提升用户留存。访问 感受更多应用性能优化体验,想阅读更多技术文章,请访问 。

本文转自

转载地址:http://vvyto.baihongyu.com/

你可能感兴趣的文章
清新脱俗的 Web 服务器 Caddy
查看>>
微服务指南走北(二):微服务架构的进程间通信(IPC)
查看>>
Webpack2.x踩坑与总结
查看>>
使用pcp监控spring boot的docker应用
查看>>
PHP微型框架设计
查看>>
关于数据缺失问题的总结
查看>>
Three.js 最新版本改进了对WebGL的支持
查看>>
微软Office 365正式上架Mac App Store
查看>>
Eclipse Collections:让Java Streams更上一层楼
查看>>
《系统与网络管理实践》(第三版)作者访谈
查看>>
除了输入法,移动端AI还有哪些想象空间?
查看>>
独家!阿里开源自用OpenJDK版本,Java社区迎来中国力量
查看>>
血淋淋的BUG:波音在软件开发上错在哪里?
查看>>
访谈:Kotlin在Pinterest的逆势生长
查看>>
云端能力知几许?12人众测华为云企业级Kubernetes集群实力
查看>>
JavaScript || this
查看>>
Safari浏览器的智能跟踪预防工作原理
查看>>
苹果iPhone X内置定制化神经引擎处理器
查看>>
Spring Web Services 3.0.4.RELEASE和2.4.3.RELEASE发布
查看>>
Microsoft Graph:连接每个应用都需要的基础数据
查看>>