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

如何将SwiftUI WebView结构体嵌套类的字符串传递到结构体绑定属性?

如何将ContentController中的response传递给WebView的Binding属性

问题场景

现有一个UIViewRepresentable实现的WebView结构体,内部嵌套的ContentController作为WKScriptMessageHandler,在验证成功(didSolve分支)时获取到了reCaptcha的响应值,需要将这个值传递给WebView的@Binding var response属性,供主ContentView使用。

原始代码片段

struct WebView: UIViewRepresentable {   
    @Binding var response: String
    
    func makeUIView(context: Context) -> WKWebView {
        let webConfiguration = WKWebViewConfiguration()
        let wkController = WKUserContentController()
        
        wkController.add(context.coordinator, name: "reCaptchaiOS")
        webConfiguration.userContentController = wkController
        // ... 其他配置代码
        return WKWebView(frame: .zero, configuration: webConfiguration)
    }
 
    func updateUIView(_ webView: WKWebView, context: Context) {
        // ... 更新逻辑
    }
    
    func makeCoordinator() -> ContentController {
        ContentController()// let handler be a coordinator
    }
    
    class ContentController: NSObject, WKScriptMessageHandler {
        // ... 其他属性
        var textResponse: String = ""
        
        func userContentController(_ userContentController: WKUserContentController,
                                   didReceive message: WKScriptMessage)  {
            if let args = message.body as? [String] {  
                switch args[0] {         
                    // ... 其他分支
                    case "didSolve":
                        self.captchaDidSolve(response: args[1])
                        textResponse = args[1]
                        break
                    // ... 其他分支
                    default:
                        print("args[0]: \(args[0])")
                        break
                }
            }
        }
            
        func captchaDidSolve(response: String) {
            print("response: \(response)")
        }
    }
}

解决方案

只需三步修改,让ContentController直接更新WebView的Binding属性:

  1. 给ContentController添加Binding属性
    在ContentController类中新增@Binding属性并补充初始化方法,用来持有WebView的response引用:

    class ContentController: NSObject, WKScriptMessageHandler {
        @Binding var response: String // 新增Binding属性
        var textResponse: String = ""
        
        // 新增初始化方法,接收Binding参数
        init(response: Binding<String>) {
            _response = response
            super.init()
        }
        
        // ... 原有方法保持不变
    }
    
  2. 在makeCoordinator时传递Binding
    修改WebView的makeCoordinator方法,将自身的response Binding传入ContentController:

    func makeCoordinator() -> ContentController {
        ContentController(response: $response)
    }
    
  3. 验证成功时更新Binding值
    在captchaDidSolve方法或didSolve分支中直接更新response属性,主ContentView会自动同步这个值:

    func captchaDidSolve(response: String) {
        print("response: \(response)")
        self.response = response // 更新Binding,主视图自动同步
    }
    

    或者直接在消息处理的分支中更新:

    case "didSolve":
        self.captchaDidSolve(response: args[1])
        textResponse = args[1]
        self.response = args[1] // 直接更新Binding
        break
    

说明

通过让ContentController持有WebView的response Binding引用,当内部获取到验证响应时,直接更新该Binding的值即可完成数据传递,主视图的绑定变量会自动同步,无需额外的通知或代理逻辑。

内容的提问来源于stack exchange,提问作者David Leyva Abrahantes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 19:31:08