swift 与JavaScript之间方法的相互调用及传值

该博客提供了一个Demo,展示了如何在Swift和JavaScript之间进行方法的相互调用以及值的传递。包括两种调用方式和两种传递方式,详细代码可在GitHub和优快云链接中查看。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Demo GitHub地址:点击打开链接  

Demo 优快云地址: 点击打开链接

如图:

此代码为swift 与JavaScript之间方法的相互调用及传值,调用方法分两种,传值方法分两种。

//
//  ViewController.swift
//  Test_js_swift
//
//  Created by gmy on 16/4/20.
//  Copyright © 2016年 dhc. All rights reserved.
//

import UIKit
import JavaScriptCore
class ViewController: UIViewController {
 
    var context = JSContext()
    var jsContext: JSContext?
    
    @IBOutlet weak var webView: UIWebView!
    override func viewDidLoad() {
        super.viewDidLoad()
        webView.delegate = self
        loadJS()
        
    }
    

    
    //MARK: - loadJS
    func loadJS() {
        let path = NSBundle.mainBundle().pathForResource("test", ofType: "html")
        let url = NSURL(fileURLWithPath: path!)
        let request = NSURLRequest(URL: url)
        webView.loadRequest(request)
    
    }
   
    // Swift 调用JS 方法 (无参数)
    @IBAction func swift_js_pargram(sender: AnyObject) {
        self.context.evaluateScript("Swift_JS1()")
//        self.webView.stringByEvaluatingJavaScriptFromString("Swift_JS1()") // 此方法也可行
    }
    
    // Swift 调用JS 方法 (有参数)
    @IBAction func swift_js_nopargam(sender: AnyObject) {
        self.context.evaluateScript("Swift_JS2('oc' ,'Swift')")
//        self.webView.stringByEvaluatingJavaScriptFromString("Swift_JS2('oc','swift')") // 此方法也可行
    }
    
    func menthod1() {
        print("JS调用了无参数swift方法")
    }
    
    func menthod2(str1: String, str2: String) {
        print("JS调用了有参数swift方法:参数为\(str1),\(str2)")
    }
    
    func webView(webView: UIWebView, didFailLoadWithError error: NSError?) {
        print(error)
    }
}

extension ViewController: UIWebViewDelegate {
    func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
        let str = NSBundle.mainBundle().pathForResource("test", ofType: "html")
        let request = NSURLRequest(URL: NSURL(string: str!)!)
        let connecntion = NSURLConnection(request: request, delegate: self)
        connecntion?.start()
        return true
    }
    
    func webViewDidStartLoad(webView: UIWebView) {
        print("webViewDidStartLoad----")
        
    }
    
    func webViewDidFinishLoad(webView: UIWebView) {
        print("webViewDidFinishLoad----")
        self.context = webView.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") as! JSContext
        // JS调用了无参数swift方法
        let temp1: @convention(block) () ->() = {
            self.menthod1()
        }
        self.context.setObject(unsafeBitCast(temp1, AnyObject.self), forKeyedSubscript: "test1")
        
        // JS调用了有参数swift方法
        let temp2: @convention(block) () ->() = {
            let array = JSContext.currentArguments() // 这里接到的array中的内容是JSValue类型
            for object in array {
                print(object)
            }
            self.menthod2(array[0].toString(), str2: array[1].toString())
        }
        self.context.setObject(unsafeBitCast(temp2, AnyObject.self), forKeyedSubscript: "test2")
        
        // 模型注入的方法
        
        let model = JSObjCModel()
        model.controller = self
        model.jsContext = context
        self.jsContext = context
        
        // 这一步是将OCModel这个模型注入到JS中,在JS就可以通过OCModel调用我们公暴露的方法了。
        self.jsContext?.setObject(model, forKeyedSubscript: "OCModel")
        let url = NSBundle.mainBundle().URLForResource("test", withExtension: "html")
        self.jsContext?.evaluateScript(try? String(contentsOfURL: url!, encoding: NSUTF8StringEncoding));
        
        self.jsContext?.exceptionHandler = {
            (context, exception) in
            print("exception @", exception)
        }

    }
    
}

@objc protocol JavaScriptSwiftDelegate: JSExport {
    func callSystemCamera()
    
    func showAlert(title: String, msg: String)
    
    func callWithDict(dict: [String: AnyObject])
    
    func jsCallObjcAndObjcCallJsWithDict(dict: [String: AnyObject])
}

@objc class JSObjCModel: NSObject, JavaScriptSwiftDelegate {
    weak var controller: UIViewController?
    weak var jsContext: JSContext?
    
    func callSystemCamera() {
        print("js call objc method: callSystemCamera");
        
        let jsFunc = self.jsContext?.objectForKeyedSubscript("jsFunc");
        jsFunc?.callWithArguments([]);
    }
    
    func showAlert(title: String, msg: String) {
        dispatch_async(dispatch_get_main_queue()) { () -> Void in
            let alert = UIAlertController(title: title, message: msg, preferredStyle: .Alert)
            alert.addAction(UIAlertAction(title: "ok", style: .Default, handler: nil))
            self.controller?.presentViewController(alert, animated: true, completion: nil)
        }
    }
    
    // JS调用了我们的方法
    func callWithDict(dict: [String : AnyObject]) {
        print("js call objc method: callWithDict, args: %@", dict)
    }
    
    // <span style="font-family: Arial, Helvetica, sans-serif;">JS调用了我们的方法</span>
    func jsCallObjcAndObjcCallJsWithDict(dict: [String : AnyObject]) {
        print("js call objc method: jsCallObjcAndObjcCallJsWithDict, args: %@", dict)
        
        let jsParamFunc = self.jsContext?.objectForKeyedSubscript("jsParamFunc");
        let dict = NSDictionary(dictionary: ["age": 18, "height": 168, "name": "lili"])
        jsParamFunc?.callWithArguments([dict])
    }
}
extension ViewController: NSURLConnectionDelegate,NSURLConnectionDataDelegate {

    func connection(connection: NSURLConnection, didReceiveData data: NSData) {
        print("didReceiveData\(data)")
    }
    
    func connection(connection: NSURLConnection, willSendRequest request: NSURLRequest, redirectResponse response: NSURLResponse?) -> NSURLRequest? {
        print("request:\(request)response:\(response)")
        return request
    }
    
    func connection(connection: NSURLConnection, didFailWithError error: NSError) {
        
    }
    
    
}





Demo代码:

点击打开链接

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值