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)
        })
    }

}

猜你喜欢

转载自blog.csdn.net/h1101723183/article/details/79241544