Search code examples
swiftcordovaswiftuicordova-pluginsqr-code

How to write a Cordova plugin with SwiftUI


I am writing a QR code scanning cordova iOS plugin. I want to use this swift package.

Right now I am experimenting by editing the code from this tutorial

Below is my code:


import SwiftUI

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

  @objc(echo:)
  func echo(command: CDVInvokedUrlCommand) {

    let ui = Button(

      action: {

        let pluginResult = CDVPluginResult(
          status: CDVCommandStatus_OK,
          messageAs: "Successful"
        )

        self.commandDelegate!.send(
          pluginResult,
          callbackId: command.callbackId
        )
      },
      label: {
        Text("Click me")
      }
    );

  }
}

I am now stuck on how to display the interface created in Swift.


Solution

  • After some research I found this to work:

    
    import SwiftUI
    import UIKit
    
    @available(iOS 13.0, *)
    @objc(ModusEchoSwift) class ModusEchoSwift : CDVPlugin {
    
      var hostingViewController = UIHostingController(rootView: ExampleView())
    
      @objc(echo:)
      func echo(command: CDVInvokedUrlCommand) {
    
        lazy var hostingViewController = UIHostingController(rootView: ExampleView(
          callbackId: command.callbackId,
          module: self
        ));
    
        self.viewController.show(hostingViewController, sender: self);
        self.hostingViewController = hostingViewController;
    
      }
    }
    
    
    @available(iOS 13.0, *)
    struct ExampleView: View {
    
      var callbackId: String?
      var module: ModusEchoSwift?
            
      var body: some View {
    
        VStack {
    
          Spacer()
    
          Text("Example")
    
          Button {
            let pluginResult = CDVPluginResult(
              status: CDVCommandStatus_OK,
              messageAs: "Successful"
            );
    
            module!.commandDelegate!.send(
              pluginResult,
              callbackId: callbackId!
            );
    
            module!.hostingViewController.dismiss(animated: true, completion: nil);
    
          } label: {
              Text("Close Me")
                .padding()
          }
    
          Spacer()
    
        }
      }
    } 
    

    I'm pretty sure that there is a better way of doing this, and I appreciate more answers from you guys.