最近一直在做有关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交互的更多相关文章

  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. IIS 7.5 Application Warm-Up Module

    http://www.cnblogs.com/shanyou/archive/2010/12/21/1913199.html 有些web应用在可以处理用户访问之前,需要装载很多的数据,或做一些花费很大 ...

  2. 人工智能与3A

    我在Tid2014上的一个小视频: 下一代的码农会是什么样的呢?且听咕咚老王的“3A”畅谈——“Ai.Art.Any”. 在艺术的视角下,世界是沉寂的.美丽的: 在码农的眼中,世界是有“码”的朦胧美吗 ...

  3. MS SQL 错误:The operation could not be performed because OLE DB provider "SQLNCLI10" for linked server "test" was unable to begin a distributed transaction.

       一同事在测试服务器(系统:Windows 2008 R2 Standard 数据库:SQL SERVER 2008 R2)通过链接服务器test使用分布式事务测试时出错,出错信息如下: set ...

  4. SQL SERVER CHAR ( integer_expression )各版本返回值差异的案例

    我们都知道CHAR(integer_expression)将ASCII代码转换为字符.当integer_expression介于 0 和 255 之间的整数.如果该整数表达式不在此范围内,将返回 NU ...

  5. Hibernate注解----类级别注解以及属性注解详解----图片版本

    这篇文章是我在慕课网上学习Hibernate注解的时候进行手机以及整理的笔记. 今天把它分享给大家,希望对大家有用.可以进行收藏,然后需要的时候进行对照一下即可.这样能起到一个查阅的作用. 本文主要讲 ...

  6. RHEL7.2和RHEL6.5的配置网络yum源和本地yum源

    RHEL7.2配置本地yum源 [root@localhost ~]#monut /dev/sr0 /mnt      #挂载光盘 [root@localhost ~]# rm -rf /etc/yu ...

  7. day1学习

    python 2 和 3 的区别 1.用户输入的命令:python 2 中是raw_input(""):python 3 中是input(""). 2.默认字符 ...

  8. windows 2012 r2下安装sharepoint 2013错误解决

    日前,我在安装sharepoint 2013时,需要预部署一些软件,我们知道运行产品准备工具“prerequisiteinstaller”后就可以自动下载安装配置这些软件,但是使用系统为windows ...

  9. 帆软报表FineReport2016年1月份产品更新一览

    .条件属性可使用页码参数插件 由于报表计算逻辑关系,条件属性中取不到页码公式.但是有些场景下又是需要在条件属性中取到页码的,比如标题只要偶数页显示,比如奇数页标题标红等等. 插件安装完成后,条件属性里 ...

  10. Workerman-文件监控-牛刀小试

    今天学习了workerman , 初次体验了定时器的效果,结合文档.弄了个文件监控. 好了 废话不多说 直接上代码 use Workerman\Worker; require_once __DIR__ ...