You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将JavaScript中的值传递到iOS UIWebView?

解决iOS UIWebView中JS带参数传递到Swift原生的问题

你的问题核心在于:当网页点击触发带参数的JS函数时,原生Swift代码无法直接获取到网页生成的参数——你之前尝试的webView.stringByEvaluatingJavaScript(from: "buttonClickPAss(a,b,c)")之所以失败,是因为Swift环境里并没有定义a、b、c这些变量,JS执行时会报错,自然没有返回值。

下面给你几种可行的解决方案,从适配UIWebView的传统方案到更推荐的现代方案都有:

方案1:自定义URL Scheme(和Android思路一致)

这是最接近你Android实现的方法,让JS通过自定义协议的URL把参数传递给原生,原生在shouldStartLoadWithRequest里解析URL参数。

修改JS代码

让buttonClickPAss函数打开一个自定义协议的URL,把参数编码后附在URL上:

function buttonClickPAss(a,b,c) {
  // 编码参数避免特殊字符问题
  const encodedA = encodeURIComponent(a);
  const encodedB = encodeURIComponent(b);
  const encodedC = encodeURIComponent(c);
  // 自定义协议:myapp://buttonclick?参数
  window.location.href = `myapp://buttonclick?a=${encodedA}&b=${encodedB}&c=${encodedC}`;
}

对应的Swift代码

在UIWebViewDelegate的shouldStartLoadWithRequest方法里拦截自定义URL并解析参数:

func webView(_ webView: UIWebView, shouldStartLoadWithRequest request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    guard let url = request.url, url.scheme == "myapp" else {
        return true // 正常加载其他HTTP/HTTPS请求
    }
    
    if url.host == "buttonclick" {
        // 解析URL里的参数
        let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
        let aValue = components?.queryItems?.first(where: { $0.name == "a" })?.value ?? ""
        let bValue = components?.queryItems?.first(where: { $0.name == "b" })?.value ?? ""
        let cValue = components?.queryItems?.first(where: { $0.name == "c" })?.value ?? ""
        
        print("从JS收到的参数:a=\(aValue), b=\(bValue), c=\(cValue)")
    }
    
    return false // 不要加载这个自定义URL,避免页面跳转
}

方案2:通过全局变量+JSON传递

如果不想用自定义URL,也可以让JS把参数存到全局变量,再通知原生去读取:

修改JS代码

// 定义全局变量存储参数
let lastClickedParams = null;

function buttonClickPAss(a,b,c) {
  lastClickedParams = {a: a, b: b, c: c};
  // 触发一个自定义URL通知原生可以读取参数了
  window.location.href = "myapp://fetchParams";
}

对应的Swift代码

func webView(_ webView: UIWebView, shouldStartLoadWithRequest request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    guard let url = request.url, url.scheme == "myapp" else {
        return true
    }
    
    if url.host == "fetchParams" {
        // 调用JS获取全局变量的JSON字符串
        let jsonString = webView.stringByEvaluatingJavaScript(from: "JSON.stringify(lastClickedParams)") ?? ""
        if !jsonString.isEmpty {
            // 解析JSON为Swift字典
            if let data = jsonString.data(using: .utf8),
               let params = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: String] {
                print("解析后的参数:\(params)")
            }
        }
        return false
    }
    
    return true
}

方案3:迁移到WKWebView(推荐)

因为UIWebView已经被苹果废弃,更推荐使用WKWebView,它提供了更安全、高效的JS-原生通信方式——WKScriptMessageHandler:

Swift代码实现

import WebKit

class YourViewController: UIViewController, WKScriptMessageHandler {
    private var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 配置WKWebView,添加消息处理器
        let config = WKWebViewConfiguration()
        config.userContentController.add(self, name: "buttonClickHandler")
        
        // 创建并添加WebView到视图
        webView = WKWebView(frame: view.bounds, configuration: config)
        view.addSubview(webView)
        
        // 加载你的HTML页面(这里直接用字符串示例,也可以加载本地/远程HTML)
        let htmlContent = """
        <html>
          <head>
            <script type="text/javascript">
              function buttonClickPAss(a,b,c) {
                // 通过WKWebView的消息机制传递参数
                window.webkit.messageHandlers.buttonClickHandler.postMessage({a: a, b: b, c: c});
                return false; // 阻止链接默认跳转
              }
            </script>
          </head>
          <body>
            <b><a href='#' onclick="buttonClickPAss('valueA','valueB','valueC');">点击这里</a></b>
          </body>
        </html>
        """
        webView.loadHTMLString(htmlContent, baseURL: nil)
    }
    
    // 接收JS发来的消息
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == "buttonClickHandler" {
            // 解析消息体里的参数
            if let params = message.body as? [String: String] {
                let a = params["a"] ?? ""
                let b = params["b"] ?? ""
                let c = params["c"] ?? ""
                print("收到JS参数:a=\(a), b=\(b), c=\(c)")
            }
        }
    }
}

这种方法不需要依赖URL跳转,通信更直接,也更符合苹果的现代开发规范。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:08:15