将数组从管理器 class 发布到 ViewModel,然后再到 View
Publishing array from a manager class to ViewModel and then to View
我正在尝试建立一个 MVVM 模式以从 BLEManager 获取值到 ViewModel,然后再到我的视图。但不知何故,我无法将 BLEManager class 中的值发送到 View Model。以下是我的数据流:
View(包含一些内容的主视图)<- View(一个包含列表的内容)<- ViewModel(将数据作为数组提供给视图中列表的视图模型)<- BleManager(ble 扫描仪到获取可用的蓝牙设备)
BleManager:
class BLEManager: NSObject, ObservableObject {
var centralManager: CBCentralManager!
@Published var peripherals = [CBPeripheral]()
@Published var isSwitchedOn = false
override init() {
super.init()
centralManager = CBCentralManager(delegate: self, queue: nil)
}
func startScanning() {
centralManager.scanForPeripherals(withServices: nil, options: nil)
}
func stopScanning() {
centralManager.stopScan()
}
}
extension BLEManager: CBCentralManagerDelegate, CBPeripheralDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == .poweredOn {
isSwitchedOn = true
}
else {
isSwitchedOn = false
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
guard let peripheralName = advertisementData[CBAdvertisementDataLocalNameKey] as? String else {
return
}
if !peripherals.contains(where: { [=11=].name == peripheralName }), let name = peripheral.name {
peripherals.append(peripheral)
}
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
peripheral.delegate = self
peripheral.discoverServices(nil)
}
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
print("didFailToConnect")
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
print("didDisconnectPeripheral")
}
}
我不知道如何为我的视图模型编写代码,以下是它的当前状态:
视图模型:
class NearbyBLEListViewModel: ObservableObject {
@Published var authenticationResult: Bool?
@Published var bleDevices = [BLEInfo]()
@Published var blutoothOff: Bool?
var bleManager = BLEManager()
func startScanning() {
bleManager.startScanning()
bleDevices = bleManager.peripherals.map { BLEInfo(bleId: [=12=].name ?? "NA", hash: "") }
// if bleManager.isSwitchedOn {
// blutoothOff = false
// bleDevices = bleManager.peripherals.map { bleInfo(bleId: [=12=].name ?? "NA", hash: "") }
// print(bleDevices)
// } else {
// blutoothOff = true
// }
}
func getBLEDevices() {
bleDevices = bleManager.peripherals.map { BLEInfo(bleId: [=12=].name ?? "NA", hash: "") }
print(bleDevices)
}
}
在视图中使用如下:
struct NearbyBLEListView: View {
@ObservedObject var bleManager = BLEManager()
@StateObject private var viewModel = NearbyBLEListViewModel()
var body: some View {
VStack {
Text("BLEs nearby:")
.font(.system(size: 22, weight: .bold, design: .default))
.padding()
.foregroundColor(.black)
List(viewModel.bleDevices) { ble in
HStack {
Text(ble.bleId)
}
}
.navigationTitle("News")
.onAppear(perform: viewModel.startScanning)
}
}
}
最后是我的最高观点:
var body: some View {
NavigationView {
VStack(alignment: .center) {
buttonView
NearbyBLEListView()
}
.navigationTitle("")
.toolbar {
moreButtonView
}
}
}
我刚刚开始使用 SwiftUI,所以我可能不了解 SwiftUI 的最佳实践。有人可以帮我吗?
摆脱视图模型对象,我们不在 SwiftUI 中使用 MVVM。 View 数据结构已经是屏幕上实际视图的模型,例如SwiftUI 为我们更新的 UILabels、UITables 等。我们可以将相关的变量和逻辑移动到自定义 @State
结构中,以使代码更易于测试,但是在您的情况下它看起来像这样:
struct NearbyBLEListView: View {
@StateObject var bleManager = BLEManager()
var body: some View {
VStack {
Text("BLEs nearby:")
.font(.system(size: 22, weight: .bold, design: .default))
.padding()
.foregroundColor(.black)
List(bleManager.bleDevices) { ble in
HStack {
Text(ble.bleId)
}
}
.navigationTitle("News")
}
}
}
当视图出现时,@StateObject
s 是初始化的,因此您可以在 BLEManager
的 init 中开始扫描。您还需要 BLEManager 来保存您的 BLEDevice
结构数组,例如
class BLEManager: NSObject, ObservableObject {
@Published var bleDevices = [BleDevice]()
我正在尝试建立一个 MVVM 模式以从 BLEManager 获取值到 ViewModel,然后再到我的视图。但不知何故,我无法将 BLEManager class 中的值发送到 View Model。以下是我的数据流:
View(包含一些内容的主视图)<- View(一个包含列表的内容)<- ViewModel(将数据作为数组提供给视图中列表的视图模型)<- BleManager(ble 扫描仪到获取可用的蓝牙设备)
BleManager:
class BLEManager: NSObject, ObservableObject {
var centralManager: CBCentralManager!
@Published var peripherals = [CBPeripheral]()
@Published var isSwitchedOn = false
override init() {
super.init()
centralManager = CBCentralManager(delegate: self, queue: nil)
}
func startScanning() {
centralManager.scanForPeripherals(withServices: nil, options: nil)
}
func stopScanning() {
centralManager.stopScan()
}
}
extension BLEManager: CBCentralManagerDelegate, CBPeripheralDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == .poweredOn {
isSwitchedOn = true
}
else {
isSwitchedOn = false
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
guard let peripheralName = advertisementData[CBAdvertisementDataLocalNameKey] as? String else {
return
}
if !peripherals.contains(where: { [=11=].name == peripheralName }), let name = peripheral.name {
peripherals.append(peripheral)
}
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
peripheral.delegate = self
peripheral.discoverServices(nil)
}
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
print("didFailToConnect")
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
print("didDisconnectPeripheral")
}
}
我不知道如何为我的视图模型编写代码,以下是它的当前状态: 视图模型:
class NearbyBLEListViewModel: ObservableObject {
@Published var authenticationResult: Bool?
@Published var bleDevices = [BLEInfo]()
@Published var blutoothOff: Bool?
var bleManager = BLEManager()
func startScanning() {
bleManager.startScanning()
bleDevices = bleManager.peripherals.map { BLEInfo(bleId: [=12=].name ?? "NA", hash: "") }
// if bleManager.isSwitchedOn {
// blutoothOff = false
// bleDevices = bleManager.peripherals.map { bleInfo(bleId: [=12=].name ?? "NA", hash: "") }
// print(bleDevices)
// } else {
// blutoothOff = true
// }
}
func getBLEDevices() {
bleDevices = bleManager.peripherals.map { BLEInfo(bleId: [=12=].name ?? "NA", hash: "") }
print(bleDevices)
}
}
在视图中使用如下:
struct NearbyBLEListView: View {
@ObservedObject var bleManager = BLEManager()
@StateObject private var viewModel = NearbyBLEListViewModel()
var body: some View {
VStack {
Text("BLEs nearby:")
.font(.system(size: 22, weight: .bold, design: .default))
.padding()
.foregroundColor(.black)
List(viewModel.bleDevices) { ble in
HStack {
Text(ble.bleId)
}
}
.navigationTitle("News")
.onAppear(perform: viewModel.startScanning)
}
}
}
最后是我的最高观点:
var body: some View {
NavigationView {
VStack(alignment: .center) {
buttonView
NearbyBLEListView()
}
.navigationTitle("")
.toolbar {
moreButtonView
}
}
}
我刚刚开始使用 SwiftUI,所以我可能不了解 SwiftUI 的最佳实践。有人可以帮我吗?
摆脱视图模型对象,我们不在 SwiftUI 中使用 MVVM。 View 数据结构已经是屏幕上实际视图的模型,例如SwiftUI 为我们更新的 UILabels、UITables 等。我们可以将相关的变量和逻辑移动到自定义 @State
结构中,以使代码更易于测试,但是在您的情况下它看起来像这样:
struct NearbyBLEListView: View {
@StateObject var bleManager = BLEManager()
var body: some View {
VStack {
Text("BLEs nearby:")
.font(.system(size: 22, weight: .bold, design: .default))
.padding()
.foregroundColor(.black)
List(bleManager.bleDevices) { ble in
HStack {
Text(ble.bleId)
}
}
.navigationTitle("News")
}
}
}
当视图出现时,@StateObject
s 是初始化的,因此您可以在 BLEManager
的 init 中开始扫描。您还需要 BLEManager 来保存您的 BLEDevice
结构数组,例如
class BLEManager: NSObject, ObservableObject {
@Published var bleDevices = [BleDevice]()