最近一直在做有关Swift和JavaScript交互的程序,所以有关UIWebView和WKWebView在使用上的差别在此总结下:

UIWebView:

(1)创建

  1. var webView: UIWebView!
  2. self.webView = UIWebView.init(frame: CGRect.init(x: 0, y: 0, width: kScreenWidth, height: kScreenHeight))
  3. self.view.addSubview(self.webView!)
  4. self.webView.delegate = self

(2)请求

  1. let url = ""
  2. let request = NSURLRequest(URL: NSURL(string: url)!)
  3. self.webView.loadRequest(request)

(3)常用代理

  1. UIWebViewDelegate
  2.  
  3. func webViewDidStartLoad(webView: UIWebView) {
  4. }
  5. func webView(webView: UIWebView, didFailLoadWithError error: NSError?) {
  6. }
  7. func webViewDidFinishLoad(webView: UIWebView) {
  8. }

UIWebView最屌的当然还是结合传说中的JavaScriptCore的Hybrid方式了

(4)在UIWebView中注入(执行)JS (注意要在webViewDidFinishLoad回调,也就是加载完后才能执行

  1. //第一种方法,直接webview执行(应该是封装了下面的方法二)
  2. let resultStr=""
  3. self.webView.stringByEvaluatingJavaScriptFromString("theFunc('"+resultStr+"');")! as String
  4.  
  5. //第二种,使用kvc来取得mainframe的context,然后执行
  6. let context = webView.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") as! JSContext
  7. context.evaluateScript(theScript)

(5)在UIWebView中监听JS的函数,这种方式可以通过原生return来call back,不过return是一种同步的call back。不是非常好。

  1. let context = webView.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") as! JSContext
  2.  
  3. //假如JS传给原生一个JSON的字符串
  4. let accountSerial: @convention(block) String -> () = { _ in
  5. let value = JSContext.currentArguments().first
  6. let data = value?.toString().dataUsingEncoding(NSUTF8StringEncoding)
  7. let accountInfoDic = try? NSJSONSerialization.JSONObjectWithData(data!, options:[]) as! NSDictionary
  8. }
  9. context.setObject(unsafeBitCast(accountSerial, AnyObject.self), forKeyedSubscript: "saveAccountInfo")
  10.  
  11. //假如需要原生return一个JSON的字符串
  12. let cookiesSerial : @convention(block) () -> String = {
  13. let cookies = NSHTTPCookieStorage.sharedHTTPCookieStorage().cookiesForURL((webView.request?.URL)!)
  14. let header=NSHTTPCookie.requestHeaderFieldsWithCookies(cookies!) as NSDictionary
  15. if(header.objectForKey("Cookie") != nil) {
  16. return cookies.toJsonString()
  17. }
  18. }

(6)另外一种奇葩的通过URL拦截的方式,让JS调用原生

http://www.cnblogs.com/rayshen/p/4560728.html

WKWebView:

(1)创建,需要import的框架和继承的协议

  1. //需要导入
  2. import WebKit
  3.  
  4. class MXWebDemoController:UIViewController,WKNavigationDelegate,WKUIDelegate,WKScriptMessageHandler{}
  5.  
  6. private var webView:WKWebView!
  7. private var progressView:UIProgressView!
  8.  
  9. //进度条
  10. progressView = UIProgressView(progressViewStyle: UIProgressViewStyle.Default)
  11. progressView.frame = CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, 22)
  12. progressView.tintColor = UIColor.blueColor()
  13. self.view.addSubview(progressView)
  14. //初始化
  15. let conf = WKWebViewConfiguration()
  16. webView = WKWebView(frame: CGRectMake(0,0,kScreenWidth,kScreenHeight), configuration: conf)
  17. self.view.insertSubview(webView, belowSubview: progressView)

(2)请求

  1. let request = NSURLRequest(URL: NSURL(string:baseUrl)!, cachePolicy: .ReloadIgnoringLocalCacheData, timeoutInterval: 10)
  2. self.webView.loadRequest(request)

(3)常用代理

  1. //webview加载完,重置进度条
  2. func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
  3. progressView.setProgress(0.0, animated: false)
  4. }
  5.  
  6. //kvo监听
  7. override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
  8. if keyPath == "estimatedProgress" {
  9. progressView.hidden = webView.estimatedProgress == 1
  10. progressView.setProgress(Float(webView.estimatedProgress), animated: true)
  11. }
  12. }
  13.  
  14. //和JS消息交互
  15. // MARK: - WKScriptMessageHandler
  16. func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
  17. if(message.name == "mxBack"){
  18. self.navigationController?.popViewControllerAnimated(true)
  19. }
  20. }

(4)JS注入,最基本的就是evaluateJavaScript函数,在页面加载完后去执行。再而,WKWebView新增了JS注入的接口。

  1. //方法1
  2. let jsStr = ""
  3. webView.evaluateJavaScript(jsStr),completionHandler: { (object, error) in
  4. if(error != nil){
  5. print(error)
  6. }
  7. })
  8.  
  9. //方法2
  10. let script = WKUserScript(source:self.scriptStr,injectionTime: .AtDocumentStart,forMainFrameOnly: true)

(5)接受来自JS的消息

  1. //
  2. conf.userContentController.addScriptMessageHandler(self, name:"mxBack")
  3.  
  4. //
  5. func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
  6. weak var weakself = self
  7. if(message.name == "mxBack"){
  8. self.hasGetResult = true
  9. self.gotoBack()
  10. }
  11. }

有关WKWebView,有个缺点,就是和JS之间没有同步的函数(依靠return来回传的方式)。

之前大部分iOS项目都是使用UIWebView,现在iOS8后Webkit良好的性能取代了UIWebView,但它的异步对很多旧的Web工程都有点影响。

别人的Demo:

https://github.com/CoderJackyHuang/WKWebViewTestDemo

下周有空我会写个更好的,更详细的介绍JS和原生之间的交互。

WKWebView与JS交互,UIWebView+JavascriptCore和JS交互的更多相关文章

  1. OC与JS交互之JavaScriptCore

    JavaScriptCore提供了JavaScript和Objective-C桥接的Obj-C API.JavaScriptCore提供了让我们脱离UIWebView执行JavaScript脚本的能力 ...

  2. iOS开发 - Swift使用JavaScriptCore与JS交互

    一.前言 在这个提倡敏捷开发和H5横行的年代,原生App内嵌入一些H5页面已经成为一种流行的趋势.一套H5页面就可以适配复杂的iOS和Android页面,大量节省了开发和维护时间,如果本来就有移动端网 ...

  3. iOS UIWebView和网页的交互(OC中调执行JS)

    UIWebView和网页的交互(OC中调执行JS)- (void)viewDidLoad{[super viewDidLoad];// 1.webViewUIWebView *webView = [[ ...

  4. iOS中UIWebView执行JS代码(UIWebView)

    iOS中UIWebView执行JS代码(UIWebView) 有时候iOS开发过程中使用 UIWebView 经常需要加载网页,但是网页中有很多明显的标记让人一眼就能看出来是加载的网页,而我们又不想被 ...

  5. 转载 OS js oc相互调用(JavaScriptCore) ---js调用iOS ---js里面直接调用方法

    OS js oc相互调用(JavaScriptCore)   接着上节我们讲到的iOS调用js 下来我们使用js调用iOS js调用iOS分两种情况 一,js里面直接调用方法 二,js里面通过对象调用 ...

  6. Android与H5交互(java与js的交互)

    一.理论概述 1.js调用java方法 直接调用WebView的该方法就可以添加接口了,不过先要启动交互 // 启用javascript mWebView.getSettings().setJavaS ...

  7. 在Ios里UIWebView参入js

    //修改图片大小适应webView宽高度            [webView stringByEvaluatingJavaScriptFromString:       @"var sc ...

  8. vue.js事件,属性,以及交互

    这是我学习vue的第二天,今天主要学习了如何利用vue阻止事件冒泡,阻止事件的默认行为,键盘事件以及如何添加class.style这些属性,以及如何利用vue来进行数据交互,利用百度的一个API来写一 ...

  9. 几十行js实现很炫的canvas交互特效

    几十行js实现很炫的canvas交互特效 废话不多说,先上效果图! 本篇文章的示例代码都是抄的一个叫Franks的老外在yutube上的一个教学视频,他还出了很多关于canvas的视频,十分值得学习, ...

随机推荐

  1. C#结合Jquery LigerUI Tree插件构造树

    Jquery LigerUI Tree是Jquery LigerUI()的插件之一,使用它可以快速的构建树形菜单.呵呵 废话不说了,直入正题,下面介绍C#结合ligerui 构造树形菜单的两种方法 1 ...

  2. 常用API——Math对象型、Number型

    Math.abs(num) : 返回num的绝对值 Math.acos(num) : 返回num的反余弦值 Math.asin(num) : 返回num的反正弦值 Math.atan(num) : 返 ...

  3. SqlServer--聚合函数

    --聚合函数默认把整个表中的数据当做"一组",然后才进行的统计. select * from NewPerson --统计出所有人的年龄的总和 select sum(age) as ...

  4. CentOS 6.6安装Xtrabackup RPM提示缺少libev.so.4()

    在CentOS Release 6.6安装percona-xtrabackup-2.3.4时,遇到下面错误信息 rpm -ivh percona-xtrabackup-2.3.4-1.el6.x86_ ...

  5. JAVA Map

    基本特性: 维持健值对的集合接口,健不可以重复,每一个健只能映射到一个值. Map替代了原来的虚拟类Directory. Map提供了三种集合视角,keys(KeySet),values(Values ...

  6. PHP中的回调函数和匿名函数

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...

  7. 7 COMPELLING REASONS YOU NEED TO START THE BUSINESS YOU’VE ALWAYS WANTED

    原文链接:http://lesseesadvocate.com/7-compelling-reasons-need-start-business-youve-always-wanted/ Don’t ...

  8. Mysql慢查询和慢查询日志分析

     Mysql慢查询和慢查询日志分析   众所周知,大访问量的情况下,可添加节点或改变架构可有效的缓解数据库压力,不过一切的原点,都是从单台mysql开始的.下面总结一些使用过或者研究过的经验,从配置以 ...

  9. RabbitMQ服务安装配置

    RabbitMQ是流行的开源消息队列系统,是AMQP(Advanced Message Queuing Protocol高级消息队列协议)的标准实现,用erlang语言开发.RabbitMQ据说具有良 ...

  10. Window下python2.7+Apache+mod_wsgi+Django服务器配置

    前言:试着使用python搭建一个网页,分别在windows下和linux下,本篇文章主要讲解Window下python+Apache+mod_wsgi+Django服务器配置过程中遇见的问题和解决方 ...