WKWebView与JS交互,UIWebView+JavascriptCore和JS交互
最近一直在做有关Swift和JavaScript交互的程序,所以有关UIWebView和WKWebView在使用上的差别在此总结下:
UIWebView:
(1)创建
- var webView: UIWebView!
- self.webView = UIWebView.init(frame: CGRect.init(x: 0, y: 0, width: kScreenWidth, height: kScreenHeight))
- self.view.addSubview(self.webView!)
- self.webView.delegate = self
(2)请求
- let url = ""
- let request = NSURLRequest(URL: NSURL(string: url)!)
- self.webView.loadRequest(request)
(3)常用代理
- UIWebViewDelegate
- func webViewDidStartLoad(webView: UIWebView) {
- }
- func webView(webView: UIWebView, didFailLoadWithError error: NSError?) {
- }
- func webViewDidFinishLoad(webView: UIWebView) {
- }
UIWebView最屌的当然还是结合传说中的JavaScriptCore的Hybrid方式了
(4)在UIWebView中注入(执行)JS (注意要在webViewDidFinishLoad回调,也就是加载完后才能执行)
- //第一种方法,直接webview执行(应该是封装了下面的方法二)
- let resultStr=""
- self.webView.stringByEvaluatingJavaScriptFromString("theFunc('"+resultStr+"');")! as String
- //第二种,使用kvc来取得mainframe的context,然后执行
- let context = webView.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") as! JSContext
- context.evaluateScript(theScript)
(5)在UIWebView中监听JS的函数,这种方式可以通过原生return来call back,不过return是一种同步的call back。不是非常好。
- let context = webView.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") as! JSContext
- //假如JS传给原生一个JSON的字符串
- let accountSerial: @convention(block) String -> () = { _ in
- let value = JSContext.currentArguments().first
- let data = value?.toString().dataUsingEncoding(NSUTF8StringEncoding)
- let accountInfoDic = try? NSJSONSerialization.JSONObjectWithData(data!, options:[]) as! NSDictionary
- }
- context.setObject(unsafeBitCast(accountSerial, AnyObject.self), forKeyedSubscript: "saveAccountInfo")
- //假如需要原生return一个JSON的字符串
- let cookiesSerial : @convention(block) () -> String = {
- let cookies = NSHTTPCookieStorage.sharedHTTPCookieStorage().cookiesForURL((webView.request?.URL)!)
- let header=NSHTTPCookie.requestHeaderFieldsWithCookies(cookies!) as NSDictionary
- if(header.objectForKey("Cookie") != nil) {
- return cookies.toJsonString()
- }
- }
(6)另外一种奇葩的通过URL拦截的方式,让JS调用原生
http://www.cnblogs.com/rayshen/p/4560728.html
WKWebView:
(1)创建,需要import的框架和继承的协议
- //需要导入
- import WebKit
- class MXWebDemoController:UIViewController,WKNavigationDelegate,WKUIDelegate,WKScriptMessageHandler{}
- private var webView:WKWebView!
- private var progressView:UIProgressView!
- //进度条
- progressView = UIProgressView(progressViewStyle: UIProgressViewStyle.Default)
- progressView.frame = CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, 22)
- progressView.tintColor = UIColor.blueColor()
- self.view.addSubview(progressView)
- //初始化
- let conf = WKWebViewConfiguration()
- webView = WKWebView(frame: CGRectMake(0,0,kScreenWidth,kScreenHeight), configuration: conf)
- self.view.insertSubview(webView, belowSubview: progressView)
(2)请求
- let request = NSURLRequest(URL: NSURL(string:baseUrl)!, cachePolicy: .ReloadIgnoringLocalCacheData, timeoutInterval: 10)
- self.webView.loadRequest(request)
(3)常用代理
- //webview加载完,重置进度条
- func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
- progressView.setProgress(0.0, animated: false)
- }
- //kvo监听
- override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
- if keyPath == "estimatedProgress" {
- progressView.hidden = webView.estimatedProgress == 1
- progressView.setProgress(Float(webView.estimatedProgress), animated: true)
- }
- }
- //和JS消息交互
- // MARK: - WKScriptMessageHandler
- func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
- if(message.name == "mxBack"){
- self.navigationController?.popViewControllerAnimated(true)
- }
- }
(4)JS注入,最基本的就是evaluateJavaScript函数,在页面加载完后去执行。再而,WKWebView新增了JS注入的接口。
- //方法1
- let jsStr = ""
- webView.evaluateJavaScript(jsStr),completionHandler: { (object, error) in
- if(error != nil){
- print(error)
- }
- })
- //方法2
- let script = WKUserScript(source:self.scriptStr,injectionTime: .AtDocumentStart,forMainFrameOnly: true)
(5)接受来自JS的消息
- //
- conf.userContentController.addScriptMessageHandler(self, name:"mxBack")
- //
- func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
- weak var weakself = self
- if(message.name == "mxBack"){
- self.hasGetResult = true
- self.gotoBack()
- }
- }
有关WKWebView,有个缺点,就是和JS之间没有同步的函数(依靠return来回传的方式)。
之前大部分iOS项目都是使用UIWebView,现在iOS8后Webkit良好的性能取代了UIWebView,但它的异步对很多旧的Web工程都有点影响。
别人的Demo:
https://github.com/CoderJackyHuang/WKWebViewTestDemo
下周有空我会写个更好的,更详细的介绍JS和原生之间的交互。
WKWebView与JS交互,UIWebView+JavascriptCore和JS交互的更多相关文章
- OC与JS交互之JavaScriptCore
JavaScriptCore提供了JavaScript和Objective-C桥接的Obj-C API.JavaScriptCore提供了让我们脱离UIWebView执行JavaScript脚本的能力 ...
- iOS开发 - Swift使用JavaScriptCore与JS交互
一.前言 在这个提倡敏捷开发和H5横行的年代,原生App内嵌入一些H5页面已经成为一种流行的趋势.一套H5页面就可以适配复杂的iOS和Android页面,大量节省了开发和维护时间,如果本来就有移动端网 ...
- iOS UIWebView和网页的交互(OC中调执行JS)
UIWebView和网页的交互(OC中调执行JS)- (void)viewDidLoad{[super viewDidLoad];// 1.webViewUIWebView *webView = [[ ...
- iOS中UIWebView执行JS代码(UIWebView)
iOS中UIWebView执行JS代码(UIWebView) 有时候iOS开发过程中使用 UIWebView 经常需要加载网页,但是网页中有很多明显的标记让人一眼就能看出来是加载的网页,而我们又不想被 ...
- 转载 OS js oc相互调用(JavaScriptCore) ---js调用iOS ---js里面直接调用方法
OS js oc相互调用(JavaScriptCore) 接着上节我们讲到的iOS调用js 下来我们使用js调用iOS js调用iOS分两种情况 一,js里面直接调用方法 二,js里面通过对象调用 ...
- Android与H5交互(java与js的交互)
一.理论概述 1.js调用java方法 直接调用WebView的该方法就可以添加接口了,不过先要启动交互 // 启用javascript mWebView.getSettings().setJavaS ...
- 在Ios里UIWebView参入js
//修改图片大小适应webView宽高度 [webView stringByEvaluatingJavaScriptFromString: @"var sc ...
- vue.js事件,属性,以及交互
这是我学习vue的第二天,今天主要学习了如何利用vue阻止事件冒泡,阻止事件的默认行为,键盘事件以及如何添加class.style这些属性,以及如何利用vue来进行数据交互,利用百度的一个API来写一 ...
- 几十行js实现很炫的canvas交互特效
几十行js实现很炫的canvas交互特效 废话不多说,先上效果图! 本篇文章的示例代码都是抄的一个叫Franks的老外在yutube上的一个教学视频,他还出了很多关于canvas的视频,十分值得学习, ...
随机推荐
- C#结合Jquery LigerUI Tree插件构造树
Jquery LigerUI Tree是Jquery LigerUI()的插件之一,使用它可以快速的构建树形菜单.呵呵 废话不说了,直入正题,下面介绍C#结合ligerui 构造树形菜单的两种方法 1 ...
- 常用API——Math对象型、Number型
Math.abs(num) : 返回num的绝对值 Math.acos(num) : 返回num的反余弦值 Math.asin(num) : 返回num的反正弦值 Math.atan(num) : 返 ...
- SqlServer--聚合函数
--聚合函数默认把整个表中的数据当做"一组",然后才进行的统计. select * from NewPerson --统计出所有人的年龄的总和 select sum(age) as ...
- 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_ ...
- JAVA Map
基本特性: 维持健值对的集合接口,健不可以重复,每一个健只能映射到一个值. Map替代了原来的虚拟类Directory. Map提供了三种集合视角,keys(KeySet),values(Values ...
- PHP中的回调函数和匿名函数
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...
- 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 ...
- Mysql慢查询和慢查询日志分析
Mysql慢查询和慢查询日志分析 众所周知,大访问量的情况下,可添加节点或改变架构可有效的缓解数据库压力,不过一切的原点,都是从单台mysql开始的.下面总结一些使用过或者研究过的经验,从配置以 ...
- RabbitMQ服务安装配置
RabbitMQ是流行的开源消息队列系统,是AMQP(Advanced Message Queuing Protocol高级消息队列协议)的标准实现,用erlang语言开发.RabbitMQ据说具有良 ...
- Window下python2.7+Apache+mod_wsgi+Django服务器配置
前言:试着使用python搭建一个网页,分别在windows下和linux下,本篇文章主要讲解Window下python+Apache+mod_wsgi+Django服务器配置过程中遇见的问题和解决方 ...