iOS中JavaScript调用Swift原生方法

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)
        })
    }
    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黄旺鑫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值