Swift 围绕第三方SDK编写联合包装器

Swift 围绕第三方SDK编写联合包装器,swift,combine,Swift,Combine,我必须在我的应用程序中使用第三方SDK,因此我认为这也是在现实生活中使用Combine并将此SDK封装在Combine helpers薄层中的绝佳机会。我能够很容易地涵盖所有内容,但现在我面临的问题是,我的一些send方法从未交付。我将分享我的一些代码,以便更好地了解我所拥有的 final class Manager: NSObject { private let sdkManager: BleManager // Private Publishers private

我必须在我的应用程序中使用第三方SDK,因此我认为这也是在现实生活中使用Combine并将此SDK封装在Combine helpers薄层中的绝佳机会。我能够很容易地涵盖所有内容,但现在我面临的问题是,我的一些
send
方法从未交付。我将分享我的一些代码,以便更好地了解我所拥有的

final class Manager: NSObject {
    private let sdkManager: BleManager

    // Private Publishers
    private let newDeviceFoundPublisher = PassthroughSubject<Device, Error>()
    private let connectedToDevicePublisher = PassthroughSubject<Device, Error>()
    private let deviceDataPublisher = PassthroughSubject<DeviceData, Never>()

    init(manager: BleManager = BleManager.shareInstance()) {
        self.vvBleManager = manager
        super.init()
        self.sdkManager.delegate = self
    }

    func startScanning(deviceType: DeviceType) -> AnyPublisher<Device, Error> {
        sdkManager.startScan(deviceType)

        return newDeviceFoundPublisher
            .map { Device.init }
            .timeout(.seconds(10), scheduler: DispatchQueue.main, customError: { .scanningTimeout })
            .eraseToAnyPublisher()
    }

    func stopScanning() {
        sdkManager.stopScan()
    }

    func connect(to device: Device) -> AnyPublisher<Device, Error> {
        sdkManager.connect(device)
        return connectedToDevicePublisher.eraseToAnyPublisher()
    }

    func disconnect(device: DeviceType) {
        sdkManager.disconnect(device)
    }

    func deviceData() -> AnyPublisher<DeviceData, Never> {
        return deviceDataPublisher.eraseToAnyPublisher()
    }
}

extension VivalnkManager: BLEDelegate {
    func onDeviceFound(_ device: Device!) {
        newDeviceFoundPublisher.send(device)
    }

    func onConnected(_ device: Device!) {
        connectedToDevicePublisher.send(device)
        connectedToDevicePublisher.send(completion: .finished)
    }

    func onReceiveData(_ data: Any!) {
        if let newData = try? DeviceData(from: data!) {
            deviceDataPublisher.send(newData)
        }
    }
}
因此,我只能在控制台中打印一段时间后才能看到
完成
,但我怀疑这是由于
超时
我的内部
扫描
方法造成的。我尝试过许多不同的方法,但都没有效果。然后,我想,也许
flatMap
不是这样工作的,所以我试着将几个
URLSession.shared.dataTaskPublisher
s嵌套在一起,它们工作得很好


更多的挖掘和我的状态,我明白为什么这一切都发生了。看起来,
sdkManager.connect(设备)
发生得太快了,以至于我的应用程序无法订阅,所以这就是我从未收到任何值的原因。对我有帮助的只是将其包装在一个延迟块中,如下所示:

func connect(to device: Device) -> AnyPublisher<Device, Error> {
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
        sdkManager.connect(device)
    }

    return connectedToDevicePublisher.eraseToAnyPublisher()
}
func连接(到设备:设备)->AnyPublisher{
DispatchQueue.main.asyncAfter(截止日期:.now()+0.1){
sdkManager.connect(设备)
}
将connectedToDevicePublisher.eraseToAnyPublisher()返回
}
现在,
connect
可以返回
AnyPublisher
,并允许订阅者在
发送之前订阅。尽管它很有效,但我觉得这是一种令人讨厌的做事方式,我对此并不满意。寻找更好的方法

func connect(to device: Device) -> AnyPublisher<Device, Error> {
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
        sdkManager.connect(device)
    }

    return connectedToDevicePublisher.eraseToAnyPublisher()
}