You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Swift代码中调用WebView内的JavaScript函数并传参?

如何在Swift中实现WebView与JavaScript的带参数fullCode交互

我来帮你搞定这个问题!你当前的Swift代码存在方法签名不匹配、未正确配置WebView交互桥接的问题,下面分两种常用的WebView场景给出完整的正确实现:

场景1:使用WKWebView(苹果推荐,iOS 8+)

WKWebView是现在苹果主推的WebView组件,用WKScriptMessageHandler来处理JS和原生的交互,步骤如下:

1. 配置WKWebView并添加消息监听

让你的ViewController遵循WKScriptMessageHandler协议,初始化WebView时配置好交互逻辑:

import UIKit
import WebKit

class ViewController: UIViewController, WKScriptMessageHandler {
    var webView: WKWebView!
    var receivedHtmlCode: String? // 存储JS传递的HTML代码

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 配置WebView参数
        let webConfig = WKWebViewConfiguration()
        let userContentController = WKUserContentController()
        
        // 添加消息监听,"fullCode"是JS调用时的标识,要和JS端对应
        userContentController.add(self, name: "fullCode")
        
        webConfig.userContentController = userContentController
        webView = WKWebView(frame: view.bounds, configuration: webConfig)
        view.addSubview(webView)
        
        // 加载你的网页(替换成你的实际URL或本地HTML路径)
        if let localHtmlPath = Bundle.main.path(forResource: "yourPage", ofType: "html") {
            let htmlUrl = URL(fileURLWithPath: localHtmlPath)
            webView.loadFileURL(htmlUrl, allowingReadAccessTo: htmlUrl.deletingLastPathComponent())
        }
    }
    
    // 接收JS消息的核心方法
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        guard message.name == "fullCode" else { return }
        
        // 解析JS传递的字符串参数
        if let htmlCode = message.body as? String {
            receivedHtmlCode = htmlCode
            print("收到JS传来的HTML代码:\(htmlCode)")
            // 这里可以添加你后续的业务逻辑
        }
    }
    
    // 记得移除监听,避免内存泄漏
    deinit {
        webView.configuration.userContentController.removeScriptMessageHandler(forName: "fullCode")
    }
}

2. 修改JavaScript代码适配WKWebView

原来的JS调用Android.fullCode需要改成WKWebView的标准调用方式:

function draft(){ 
  var getAllHtmlCode = getHtml(); 
  window.webkit.messageHandlers.fullCode.postMessage(getAllHtmlCode); 
}

场景2:使用UIWebView(不推荐,iOS 12+已废弃)

如果你的项目还在使用旧的UIWebView,可以用JavaScriptCore框架实现:

1. 配置UIWebView并注入JS桥接对象

import UIKit
import JavaScriptCore

class ViewController: UIViewController, UIWebViewDelegate {
    var webView: UIWebView!
    var receivedHtmlCode: String?
    
    // 定义JS导出协议,必须继承JSExport
    @objc protocol WebViewJSBridge: JSExport {
        // 方法名要和JS里的`fullCode`完全一致(注意大小写!)
        func fullCode(_ htmlCode: String)
    }
    
    // 实现桥接逻辑的类
    @objc class JSBridgeHandler: NSObject, WebViewJSBridge {
        weak var parentVC: ViewController?
        
        init(vc: ViewController) {
            parentVC = vc
        }
        
        func fullCode(_ htmlCode: String) {
            parentVC?.receivedHtmlCode = htmlCode
            print("收到JS传来的HTML代码:\(htmlCode)")
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        
        webView = UIWebView(frame: view.bounds)
        webView.delegate = self
        view.addSubview(webView)
        
        // 加载你的网页
        if let localHtmlPath = Bundle.main.path(forResource: "yourPage", ofType: "html") {
            let htmlUrl = URL(fileURLWithPath: localHtmlPath)
            webView.loadRequest(URLRequest(url: htmlUrl))
        }
    }
    
    // 网页加载完成后注入桥接对象
    func webViewDidFinishLoad(_ webView: UIWebView) {
        guard let jsContext = webView.value(forKeyPath: "documentView.webView.mainFrame.javaScriptContext") as? JSContext else { return }
        
        // 注入名为"Android"的桥接对象,和你原JS代码的调用保持一致
        let bridge = JSBridgeHandler(vc: self)
        jsContext.setObject(bridge, forKeyedSubscript: "Android" as (NSCopying & NSObjectProtocol))
    }
}

2. 保持原JavaScript代码不变

这种情况下,你原来的JS代码Android.fullCode(getAllHtmlCode)可以直接使用,不需要修改。


几个关键注意点

  • 方法名大小写必须一致:你原来的Swift代码写的是fullcode(小写c),但JS里调用的是fullCode(大写C),这会导致无法匹配,一定要统一!
  • 参数类型要匹配:确保JS传递的参数类型和Swift接收的类型一致,这里是字符串,所以转成String即可。
  • 优先使用WKWebView:UIWebView已经被苹果废弃,不再提供更新和维护,建议新项目或迭代时切换到WKWebView。

内容的提问来源于stack exchange,提问作者Faizul Karim

火山引擎 最新活动