如何存储在委托类中接收的值,在外部类中?
有一个BLEManager类,负责扫描、连接和接收来自蓝牙低能耗(BLE)设备的数据。看起来是这样的:
SwiftUI或UIKit,一旦您在某个地方实例化了
class BLEManager: ObservableObject, OtherProtocols {
private var myCentral: CBCentralManager!
@Published var data = 0.0
override init() {
super.init()
myCentral = CBCentralManager(delegate: self, queue: nil)
myCentral.delegate = self
}
// ...some functions that scan, establish connection, etc.
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
// here I receive raw value, handle it and get a data to work with
data = 10.0 // imagine it's the data received from BLE device
}
}
现在,要使用的数据存储在这个类中。我想以这种方式移动这些数据,因此当前类(BLEManager)只负责BLE逻辑,数据与其他用户数据一起存储。 在SWIFT中可能吗?
附注:我是斯威夫特的新手。有JS经验。
编辑
在当前情况下,BLEManager从一个特定的外围设备接收数据。明确地说,这些数据代表了人类的体重。除此之外,还有一个包含人类生物特征数据(年龄、身高、性别)的结构。归根结底,生物特征数据+来自设备(体重)的数据密切相关,并在相同的计算中使用。结果
我能够实现Cristik的方法。唯一的区别是,在我的例子中,替换发生在View的.onAppear()
修饰符中,而不是像他描述的那样发生在类init上。将发布者传递给类时遇到问题。
解决方案
我想以这种方式移动这些数据,这样当前类(BLEManager)只负责BLE逻辑,数据与其他用户数据一起存储
这是一个很好的心态,因为目前你的BLEManager
打破了单一责任原则,即有多个责任。ObservedObject
部分是SwiftUI特定的部分,因此从类中提取是有意义的。
data
属性转换为发布者。这将允许客户端连接到数据流,并允许您在应用的其余部分中循环发布者,而不是BLEManager
类。
import Combine
class BLEManager: OtherProtocols {
// you can use `Error` instead of `Never` if you also want to
// report errors which make the stream come to an end
var dataPublisher: AnyPublisher<Int, Never> { _dataPublisher.eraseToAnyPublisher() }
private var myCentral: CBCentralManager!
// hiding/encapsulating the true nature of the publisher
private var _dataPublisher = PassthroughSubject<Int, Never>()
// ...
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
_dataPublisher.send(10.0) // imagine it's the data received from BLE device
}
这样,任何有兴趣接收BLE数据的人都可以直接订阅该发布者。
现在,在接收端,假设您的SwiftUI视图也需要ObservableObject
,您可以编写以下内容:
class ViewModel: ObservableObject {
@Published var data: Int = 0
init(dataPublisher: AnyPublisher<Int, Never>) {
// automatically updates `data` when new values arrive
dataPublisher.assign(to: &$data)
}
}
如果您不使用SwiftUI(由于ObservableObject
一致性,我假设您使用),则您可以sink
到同一发布者以接收数据。
SwiftUI或UIKit,一旦您在某个地方实例化了
BLEManager
,您可以对应用程序的其余部分隐藏它,并通过传播发布者来提供订阅BLE数据的方法。这也有助于分离应用程序其余部分的关注点。
相关文章