将 ACSSmartCardIO 和 SmartCardIO 集成到 SwiftUI 项目中

Integrate ACSSmartCardIO & SmartCardIO into a SwiftUI project

我面临的问题是我想将以下框架集成到 SwiftUI 项目中,即:ACSSmartCardIO 和 SmartCardIO

我不精通 SwiftUI 或 iOS 开发以了解如何实现委托并在 SwiftUI 中使用它。

文档显示: 在连接蓝牙卡终端之前,您的应用程序必须导入 ACSSmartCardIO 模块。您可以从 BluetoothSmartCard.shared 对象中获取蓝牙终端管理器和终端工厂的实例。要从 BluetoothTerminalManager 对象接收事件,您的应用必须为其分配一个委托对象。

...

import SmartCardIO
import ACSSmartCardIO

...

class ViewController: UIViewController {

    ...

    let manager = BluetoothSmartCard.shared.manager
    let factory = BluetoothSmartCard.shared.factory

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        ...

        // Set the delegate.
        manager.delegate = self

        ...
    }

    ...
}

...

您的应用必须检查 CentralManager 对象的状态,并在不支持蓝牙或其他原因导致您的应用无法在 iOS 设备上使用蓝牙时显示消息。

// MARK: - BluetoothTerminalManagerDelegate
extension ViewController: BluetoothTerminalManagerDelegate {

    func bluetoothTerminalManagerDidUpdateState(_ manager: BluetoothTerminalManager) {

        var message = ""

        switch manager.centralManager.state {

        case .unknown, .resetting:
            message = "The update is being started. Please wait until Bluetooth is ready."

        case .unsupported:
            message = "This device does not support Bluetooth low energy."

        case .unauthorized:
            message = "This app is not authorized to use Bluetooth low energy."

        case .poweredOff:
            if !firstRun {
                message = "You must turn on Bluetooth in Settings in order to use the reader."
            }

        default:
            break
        }

        if !message.isEmpty {

            // TODO: Show the message.
            // ...
        }

        firstRun = false
    }

    ...
}

要查找 BLE 卡终端,您必须使用 BluetoothTerminalManager 对象中的 BluetoothTerminalManager.startScan(terminalType:) 方法。

...

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if let identifier = segue.identifier {
        switch identifier {

        case "ScanTerminals":

            ...

            // Start the scan.
            manager.startScan(terminalType: .amr220c)

            ...

        default:
            break
        }
    }
}

...

您的代码与 UI 关系不大。 SwiftUI 仅在直接处理用户交互时才重要。

将此代码应用于 SwiftUI 设置的一种简单方法是将 UIViewController 中的所有代码放入 ObservableObject.[= 的 ViewModel 中25=]

替换

class ViewController: UIViewController {

class BluetoothSmartCardViewModel: ObservableObject {

extension ViewController: BluetoothTerminalManagerDelegate {

extension BluetoothSmartCardViewModel: BluetoothTerminalManagerDelegate {

使用任何 UIKit 代码(例如 IBActionIBOutlet 和任何 viewDid... 方法,您都会遇到一些错误。您将必须创建 @Published 变量和 func 来补偿那些与 SwiftUI View 与 Storyboard 交互的变量。

segue 代码而言,这似乎是“最棘手”的部分。有几种处理方法。

一种方法是 ScanTerminalsView

.onAppear(){
    viewModel.manager.startScan(terminalType: .amr220c)
}