iOS与前端交互 — Swift 与 Vue 2.0的交互

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_30932479/article/details/89087429

前提是前端用的Vue写的代码,普通HTML看下一篇。

先看交互效果:

 

上图是一个Swift加载的web界面,按钮”下一步“触发app端的一个事件,在此事件中app调用前端的alert方法出现弹框。看起来很简单的过程,我跟前端人员硬是调了两天。

先看Swift端的代码:

// 定义协议SwiftJavaScriptDelegate 该协议必须遵守JSExport协议
@objc protocol SwiftJavaScriptDelegate: JSExport {
    // js调用App方法,传递图片image参数
    func idCardImage(_ frontImage: String,_ backImage: String,_ jsFuncName:String)
}

// 定义一个模型 该模型实现SwiftJavaScriptDelegate协议
@objc class SwiftJavaScriptModel: NSObject, SwiftJavaScriptDelegate {
    
    weak var controller: UIViewController?
    weak var jsContext: JSContext?
    
    // js调用App方法,传递图片image参数
    func idCardImage(_ frontImage: String,_ backImage: String,_ jsFuncName:String) {
        let a = self.jsContext?.objectForKeyedSubscript("payResult")
        a?.call(withArguments: [])
    }

}

写一个跟JS交互的协议,idCardImage方法将暴露给JS端。

class CCWKWebViewController: CCBaseVC {
    
    var webView: UIWebView!
    var jsContext: JSContext!
    var completedCallBack:(()->())?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        setWebView()
    }
    
    func setWebView(){
        
        webView = UIWebView(frame: self.view.bounds)
        view.addSubview(webView)
        webView.delegate = self
        webView.scalesPageToFit = true
        
        // 测试加载本地Html页面
        let path = Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "dist 14")
        let url = URL.init(fileURLWithPath: path!)
        let request = URLRequest(url: url)
        
        webView.loadRequest(request)
    }
    
    func setContext(){
        
        self.jsContext = webView.value(forKeyPath: "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" as NSCopying & NSObjectProtocol)
        
        // 注册到网络Html页面 请设置允许Http请求
        let curUrl = self.webView.request?.url?.absoluteString  //WebView当前访问页面的链接 可动态注册
        self.jsContext.evaluateScript(curUrl)
        
        self.jsContext.exceptionHandler = { (context, exception) in
            print("exception:", exception as Any)
        }
    }
    
}

加载web并配置jsContext,setContext是将JSContext协议方法注入到JS中,后面JS调用App端方法失败,就从这里找原因。

再看Vue端的代码,

        mounted(){
			window.payResult = this.payResult
		},
	methods: {
			
			callApp(){
				        WebViewJavascriptBridge.idCardImage("123","456","payResult");
			},
			
			payResult:function() {
				alert('你好');
			},
               }

其中,callApp方法就是按钮下一步触发的方法,WebViewJavascriptBridge.idCardImage("123","456","payResult"),意思是调用App端暴露出来的idCardImage(param,param,param)方法,这里的方法名必须跟app端的一致,不然找不到方法,”123“, ”456“, "payResult" 是传给app端的三个参数,看app端代码:

 // js调用App方法,传递图片image参数
    func idCardImage(_ frontImage: String,_ backImage: String,_ jsFuncName:String) {
        let a = self.jsContext?.objectForKeyedSubscript("\(jsFuncName)")
        a?.call(withArguments: [])
    }

第三个参数传的是JS那边的方法,该方法是需要app端调用的,所以就是js调用idCardImage()方法传给app参数”123“,”456“,”payResult“字符串接收后在app端解析出js方法,然后通过call(withArguments:)方法调用js的payResult方法弹出alert。

 

注意:我在项目中遇到App端无法调用Vue JS方法的问题,网上找了很多demo调用都很正常,只是demo里是普通的html代码,后来调查发现,vue中的js方法必须注册到window全局中,app端才能调用成功,所以这里要注意方Vue中mounted( )方法中的代码:window.payResult = this.payResult

没有更多推荐了,返回首页