JavaScript调用Swift原生方法
1、创建公开给JavaScript调用的方法类
2、导入JavaScriptCore库
3、关联JSContext
4、以 JSExport 协议关联 NativeObject对象的方法
5、实现JSMethodExport协议方法
// 获取JSContext Key
public let JavaScriptContext_Key = "documentView.webView.mainFrame.javaScriptContext"
import UIKit
import JavaScriptCore
class JSMethodExportViewController: UIViewController {
@IBOutlet weak var webView: UIWebView!
var context: JSContext?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
webView.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
deinit {
URLCache.shared.removeAllCachedResponses()
// 防止销毁时未移除导致闪退
NotificationCenter.default.removeObserver(self)
if webView == nil {
return
}
webView.stopLoading()
webView.delegate = nil
webView.loadRequest(URLRequest(url: "about:blank".URL! as URL))
}
}
extension JSMethodExportViewController: UIWebViewDelegate, JSMethodExport {
func webViewDidStartLoad(_ webView: UIWebView) {
// 建立关联关系
context = webView.value(forKeyPath: JavaScriptContext_Key) as? JSContext
// 以 JSExport 协议关联 native 的方法
context?.setObject(self, forKeyedSubscript: "NativeObject" as (NSCopying & NSObjectProtocol)!)
context?.evaluateScript("NativeObject.isiOS=true;")
context?.exceptionHandler = { (context, exception) in
print(context, exception)
}
}
}
@objc protocol JSMethodExport: JSExport {
/**
获取城市定位
*/
func getCity()
/**
传递城市信息
- parameter cityId: 城市Id
- parameter cityName: 城市名字
*/
func postCity(_ cityId: Int, cityName: String)
/**
返回上一页
*/
func finishView()
func popTwoView()
/**
跳转商家地图
- parameter lat: <#lat description#>
- parameter lng: <#lng description#>
- parameter name: 商家名称
- parameter address: 地址
*/
func locationMap(_ params: [AnyObject])
func tolocationMap(_ params: [AnyObject])
/**
调用获取Token
*/
func getToken()
/**
跳转设置
*/
func setting()
/**
分享App给朋友
*/
func shareApp()
/**
分享商铺给朋友(企业id)
- parameter id: 企业Id
*/
func shareShop(_ id: Int)
/**
跳转到编辑轮播图
*/
func editCarousel()
/**
跳转到编辑企业
- parameter id: 企业Id
*/
func editCompany(_ id: Int)
/**
跳转到编辑商品
- parameter productId: 商品Id
*/
func editGoods(_ productId: Int)
/**
跳转发布商品
*/
func publishGoods()
}
extension WebViewController {
// MARK: - UIWebViewDelegate
func webViewDidFinishLoad(_ webView: UIWebView) {
context = webView.value(forKeyPath: JavaScriptContext_Key) as? JSContext
// 以 JSExport 协议关联 native 的方法
context?.setObject(self, forKeyedSubscript: "NativeObject" as (NSCopying & NSObjectProtocol)!)
}
// MARK: - JSMethodExport
/**
跳转到搜索页
*/
override func locationSearch() {
let instance = WebViewController.webInstance()
instance.viewType = WebViewController.ViewType.SearchProduct
// 主线程
DispatchQueue.main.async(execute: { [weak self] () -> Void in
self?.navigationController?.pushViewController(instance, animated: true)
})
}
/**
跳转到搜索结果页
- parameter text: 关键字
*/
override func locationResult(_ text: String) {
let instance = WebViewController.webInstance()
instance.viewType = WebViewController.ViewType.SearchProductResult
if let text = text.addingPercentEscapes(using: String.Encoding.utf8) {
instance.parameter = "?text=\(text)"
}
// 主线程
DispatchQueue.main.async(execute: { [weak self] () -> Void in
self?.navigationController?.pushViewController(instance, animated: true)
})
}
/**
跳转城市选择页
*/
override func locationCity() {
// 跳转选择城市
let instance = CityManagerViewController.cityManagerInstance()
// 主线程
DispatchQueue.main.async(execute: { [weak self] () -> Void in
self?.navigationController?.pushViewController(instance, animated: true)
})
}
/**
跳转到头条详情
- parameter newsId: 资讯Id
*/
override func locationNewsDetaile(_ newsId: Int) {
let instance = WebViewController.webInstance()
instance.viewType = WebViewController.ViewType.NewsDetail
instance.parameter = "?id=\(newsId)"
// 主线程
DispatchQueue.main.async(execute: { [weak self] () -> Void in
self?.navigationController?.pushViewController(instance, animated: true)
})
}
/**
跳转到企业详情
- parameter enterpriseId: 企业Id
*/
override func locationCompanyDetaile(_ enterpriseId: Int) {
// 跳转企业详情
let instance = DetailViewController.detailInstance()
instance.isProductDetail = false
instance.enterpriseId = enterpriseId
// 主线程
DispatchQueue.main.async(execute: { [weak self] () -> Void in
self?.navigationController?.pushViewController(instance, animated: true)
})
}
/**
调用获取商品Id列表
*/
override func getProductIdList() {
// 传递商品列表
var productIds = [Int]()
// 最近浏览
if viewType == .RecentlyViewed {
productIds = DataManager.sharedInstance.recentlyViewedProductIds
}
context?.evaluateScript("pTool.getProductIdList(\(productIds))")
}
/**
清空浏览记录
*/
override func clearHistory() {
DataManager.cleanRecentlyViewed()
}
/**
跳转搜索企业页
*/
override func locationSearchCompany() {
let instance = WebViewController.webInstance()
instance.viewType = WebViewController.ViewType.SearchEnterprise
// 主线程
DispatchQueue.main.async(execute: { [weak self] () -> Void in
self?.navigationController?.pushViewController(instance, animated: true)
})
}
/**
跳转企业搜索结果页
- parameter text: 关键字
*/
override func locationCompanyResult(_ text: String) {
let instance = WebViewController.webInstance()
instance.viewType = WebViewController.ViewType.SearchEnterpriseResult
if let text = text.addingPercentEscapes(using: String.Encoding.utf8) {
instance.parameter = "?text=\(text)"
}
// 主线程
DispatchQueue.main.async(execute: { [weak self] () -> Void in
self?.navigationController?.pushViewController(instance, animated: true)
})
}
}