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

如何使用SwiftUI编写Cordova iOS插件并展示Swift创建的界面

Cordova iOS插件展示SwiftUI界面实现方案

核心逻辑:Cordova iOS插件运行在WebView容器中,CDVPlugin类本身不直接管理视图层级,要展示SwiftUI编写的原生界面,必须通过Cordova持有的根视图控制器,用UIHostingController承载SwiftUI内容后弹出,仅初始化SwiftUI控件不挂载到视图层级不会有任何界面展示。

前置配置

  • 确保插件工程已开启Swift编译支持,集成好CodeScanner组件
  • 在iOS工程Info.plist中添加NSCameraUsageDescription字段,描述相机使用用途,避免扫码功能触发权限崩溃

参考实现代码

import SwiftUI
import CodeScanner

// 自定义SwiftUI界面,可直接替换为扫码视图
@available(iOS 13.0, *)
struct PluginContentView: View {
    var onDismiss: () -> Void
    var onResultCallback: (String) -> Void
    
    var body: some View {
        // 测试按钮,正式使用时替换为CodeScannerView即可
        VStack(spacing: 20) {
            Button(action: {
                onResultCallback("操作成功")
                onDismiss()
            }) {
                Text("点击触发操作")
                    .padding()
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(8)
            }
        }
        // 扫码功能接入示例
        // CodeScannerView(codeTypes: [.qr], completion: { response in
        //     switch response {
        //     case .success(let scanResult):
        //         onResultCallback(scanResult.string)
        //         onDismiss()
        //     case .failure(let err):
        //         onResultCallback("扫码失败:\(err.localizedDescription)")
        //         onDismiss()
        //     }
        // })
    }
}

@available(iOS 13.0, *)
@objc(ModusEchoSwift) class ModusEchoSwift : CDVPlugin {

  @objc(echo:)
  func echo(command: CDVInvokedUrlCommand) {
    // *所有UI操作必须切换到主线程执行,否则会出现界面不弹出、卡顿、崩溃问题
    DispatchQueue.main.async {
        let contentView = PluginContentView(
            onDismiss: { [weak self] in
                self?.viewController.dismiss(animated: true)
            },
            onResultCallback: { [weak self] result in
                let pluginResult = CDVPluginResult(
                    status: CDVCommandStatus_OK,
                    messageAs: result
                )
                self?.commandDelegate!.send(
                    pluginResult,
                    callbackId: command.callbackId
                )
            }
        )
        let hostingVC = UIHostingController(rootView: contentView)
        if #available(iOS 13.0, *) {
            hostingVC.modalPresentationStyle = .fullScreen
        }
        self.viewController.present(hostingVC, animated: true)
    }
  }
}

注意事项

  • 不要在子线程执行任何UI相关操作
  • 扫码场景建议将模态弹出样式设为全屏,避免默认半屏Sheet影响扫码体验
  • 首次触发扫码时系统会自动弹出相机权限申请,无需额外手动触发
  • 拿到扫码结果后要主动调用dismiss关闭原生界面,回到Cordova WebView页面

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 03:54:31