Swift使用JavaScriptCore与JS交互,让Native和HTML5共舞

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
查看查看306 回复回复3 收藏收藏1 分享淘帖 转播转播 分享分享 微信
查看: 306|回复: 3
收起左侧

Swift使用JavaScriptCore与JS交互,让Native和HTML5共舞

[复制链接]
SwiftRobot 发表于 2016-7-5 22:35:11 | 显示全部楼层 |阅读模式
快来登录
获取优质的苹果资讯内容
收藏热门的iOS等技术干货
拷贝下载Swift Demo源代码
订阅梳理好了的知识点专辑


1、前言

在这个提倡敏捷开发和H5横行的年代,原生App内嵌入一些H5页面已经成为一种流行的趋势。一套H5页面就可以适配复杂的iOS和Android页面,大量节省了开发和维护时间,如果本来就有移动端网页,只需简单适配即可完成,那我们何乐而不为呢?苹果也顺应了潮流,在iOS7中提供了JavaScriptCore框架用来与网页中的JS进行交互。还有Facebook推出的React Native,也给跨平台开发提供了新的思路和解决方案,虽然目前它还不是很成熟。但作为一个开发者,对这些新技术的出现自然会感到无比的兴奋。本文主要介绍iOS开发中,Swift如何使用JavaScriptCore与网页中的JS进行交互。




2、JavaScriptCore中的类

  • JSContext:JSContext是JS的执行环境,通过evaluateScript()方法可以执行JS代码
  • JSValue:JSValue封装了JS与ObjC中的对应的类型,以及调用JS的API等
  • JSExport:JSExport是一个协议,遵守此协议,就可以定义我们自己的协议,在协议中声明的API都会在JS中暴露出来,这样JS才能调用原生的API





3、交互方式主要有两种



3.1、 在Swift中,通过JSContext直接执行JS代码

[Swift] 纯文本查看 复制代码
import JavaScriptCore    //记得导入JavaScriptCore


// 通过JSContext执行js代码
let context: JSContext = JSContext()
let result1: JSValue = context.evaluateScript("1 + 3")
print(result1)  // 输出4

// 定义js变量和函数
context.evaluateScript("var num1 = 10; var num2 = 20;")
context.evaluateScript("function sum(param1, param2) { return param1 + param2; }")

// 通过js方法名调用方法
let result2 = context.evaluateScript("sum(num1, num2)")
print(result2)  // 输出30

// 通过下标来获取js方法并调用方法
let squareFunc = context.objectForKeyedSubscript("sum")
let result3 = squareFunc.callWithArguments([10, 20]).toString()
print(result3)  // 输出30




3.2、在Swift中通过JSContext注入模型,然后调用模型的方法


3.2.1、首先定义定义协议SwiftJavaScriptDelegate,该协议必须遵守JSExport协议

[Swift] 纯文本查看 复制代码
@objc protocol SwiftJavaScriptDelegate: JSExport {
    
    // js调用App的微信支付功能 演示最基本的用法
    func wxPay(orderNo: String)
    
    // js调用App的微信分享功能 演示字典参数的使用
    func wxShare(dict: [String: AnyObject])
    
    // js调用App方法时传递多个参数 并弹出对话框 注意js调用时的函数名
    func showDialog(title: String, message: String)
    
    // js调用App的功能后 App再调用js函数执行回调
    func callHandler(handleFuncName: String)
    
}



3.2.2、然后定义一个模型,该模型实现SwiftJavaScriptDelegate协议

[Swift] 纯文本查看 复制代码
@objc class SwiftJavaScriptModel: NSObject, SwiftJavaScriptDelegate {
    
    weak var controller: UIViewController?
    weak var jsContext: JSContext?
    
    func wxPay(orderNo: String) {
    
        print("订单号:", orderNo)
        
        // 调起微信支付逻辑
    }
    
    func wxShare(dict: [String: AnyObject]) {
        
        print("分享信息:", dict)
        
        // 调起微信分享逻辑
    }
    
    func showDialog(title: String, message: String) {
        
        let alert = UIAlertController(title: title, message: message, preferredStyle: .Alert)
        alert.addAction(UIAlertAction(title: "确定", style: .Default, handler: nil))
        self.controller?.presentViewController(alert, animated: true, completion: nil)
    }
    
    func callHandler(handleFuncName: String) {
        
        let jsHandlerFunc = self.jsContext?.objectForKeyedSubscript("\(handleFuncName)")
        let dict = ["name": "sean", "age": 18]
        jsHandlerFunc?.callWithArguments([dict])
    }
}



3.2.3、然后使用WebView加载对应的网页,这里加载例子中的demo.html文件

[Swift] 纯文本查看 复制代码
func addWebView() {
    
    self.webView = UIWebView(frame: self.view.bounds)
    self.view.addSubview(self.webView)
    self.webView.delegate = self
    self.webView.scalesPageToFit = true
    
    // 加载本地Html页面
    let url = NSBundle.mainBundle().URLForResource("demo", withExtension: "html")
    let request = NSURLRequest(URL: url!)
    
    // 加载网络Html页面 请设置允许Http请求
    //let url = NSURL(string: "http://www.mayanlong.com");
    //let request = NSURLRequest(URL: url!)
    
    self.webView.loadRequest(request)
}



3.2.4、最后在webViewDidFinishLoad代理中将我们定义的模型注入到网页中,暴露给JS

[Swift] 纯文本查看 复制代码
func webViewDidFinishLoad(webView: UIWebView) {
    
    
    self.jsContext = webView.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") as! JSContext
    let model = SwiftJavaScriptModel()
    model.controller = self
    model.jsContext = self.jsContext
    
    // 这一步是将SwiftJavaScriptModel模型注入到JS中,在JS就可以通过WebViewJavascriptBridge调用我们暴露的方法了。
    self.jsContext.setObject(model, forKeyedSubscript: "WebViewJavascriptBridge")
    
    // 注册到本地的Html页面中
    let url = NSBundle.mainBundle().URLForResource("demo", withExtension: "html")
    self.jsContext.evaluateScript(try? String(contentsOfURL: url!, encoding: NSUTF8StringEncoding))
    
    // 注册到网络Html页面 请设置允许Http请求
    //let url = "http://www.mayanlong.com";
    //let curUrl = self.webView.request?.URL?.absoluteString    //WebView当前访问页面的链接 可动态注册
    //self.jsContext.evaluateScript(try? String(contentsOfURL: NSURL(string: url)!, encoding: NSUTF8StringEncoding))

    self.jsContext.exceptionHandler = { (context, exception) in
        print("exception:", exception)
    }
}



3.2.5、Swift与JS方法互相调用


3.2.5.1、JS调用Swift方法

[Swift] 纯文本查看 复制代码
WebViewJavascriptBridge.wxPay('TN20160526')

WebViewJavascriptBridge.wxShare({
            'title' : '敏捷大拇指',
            'description' : '全球最大的Swift开发者社区',
            'url' : 'http://www.swifthumb.com'
        })

WebViewJavascriptBridge.showDialogMessage('敏捷大拇指', '全球最大的Swift开发者社区')



3.2.5.2、Swift调用JS方法并传参

[Swift] 纯文本查看 复制代码
func callHandler(handleFuncName: String) {
    
    let jsHandlerFunc = self.jsContext?.objectForKeyedSubscript("\(handleFuncName)")
    let dict = ["name": "sean", "age": 18]
    jsHandlerFunc?.callWithArguments([dict])
}


这样,我们就实现了Swift与JS的交互了,Demo中给出了详细的代码,大家可以下载运行。




4、代码下载及效果图



4.1、下载地址:

Github地址:

游客,如果您要查看本帖隐藏内容请回复


如果本Demo对您有帮助,请不要吝啬您的Star(⊙o⊙)哦。



4.2、效果图:

Swift使用JavaScriptCore与JS交互

Swift使用JavaScriptCore与JS交互,让Native和HTML5共舞 - 敏捷大拇指 - Swift使用JavaScriptCore与JS交互





5、相关内容

第三方类Reachability:用Swift实现检测网络连接状态及网络类型

Swift实现清除缓存功能、统计大小,源代码拷过去直接用!

Swift使用JavaScriptCore与JS交互,让Native和HTML5共舞




作者:马燕龙

都看到这里了,就把这篇资料推荐给您的好朋友吧,让他们也感受一下。

回帖是一种美德,也是对楼主发帖的尊重和支持。

*声明:敏捷大拇指是全球最大的Swift开发者社区、苹果粉丝家园、智能移动门户,所载内容仅限于传递更多最新信息,并不意味赞同其观点或证实其描述;内容仅供参考,并非绝对正确的建议。本站不对上述信息的真实性、合法性、完整性做出保证;转载请注明来源并加上本站链接,敏捷大拇指将保留所有法律权益。如有疑问或建议,邮件至marketing@swifthumb.com

*联系:微信公众平台:“swifthumb” / 腾讯微博:@swifthumb / 新浪微博:@swifthumb / 官方QQ一群:343549891(满) / 官方QQ二群:245285613 ,需要报上用户名才会被同意进群,请先注册敏捷大拇指

嗯,不错!期待更多好内容,支持一把:
支持敏捷大拇指,用支付宝支付10.24元 支持敏捷大拇指,用微信支付10.24元

评分

参与人数 1金钱 +10 贡献 +10 专家分 +10 收起 理由
Anewczs + 10 + 10 + 10 32个赞!专家给力!

查看全部评分

本帖被以下淘专辑推荐:

yadan 发表于 2016-7-7 09:14:15 | 显示全部楼层
CSS是不是也有个CSSCore?
 楼主| SwiftRobot 发表于 2016-7-13 23:10:37 | 显示全部楼层
yadan 发表于 2016-7-7 09:14
CSS是不是也有个CSSCore?

应该可以有。
jswift 发表于 2016-10-24 10:33:58 | 显示全部楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

做任务,领红包。
我要发帖

分享扩散

都看到这里了,就把这资料推荐给您的好朋友吧,让他们也感受一下。
您的每一位朋友访问此永久链接后,您都将获得相应的金钱积分奖励
热门推荐

合作伙伴

Swift小苹果

  • 北京治世天下科技有限公司
  • ©2014-2016 敏捷大拇指
  • 京ICP备14029482号
  • Powered by Discuz! X3.1 Licensed
  • swifthumb Wechat Code
  •   
快速回复 返回顶部 返回列表