提问人:Madushan Senavirathna 提问时间:9/22/2023 最后编辑:Madushan Senavirathna 更新时间:9/22/2023 访问量:39
需要实时更新 UITableViewCell 数据
Need to update UITableViewCell data real time
问:
我正在开发蓝牙应用程序,从广播设备获取设备数据,所有数据都没有任何问题,我们用这个代码来测试我们的设备,这个代码库只过滤那些设备
let deviceLocations: [字符串: 字符串] = [ “00000534”: “办公室”, “00000523”: “接待处”, “00000525”: “午餐室” ]
我为此目的添加了 所有人都在解决任何问题
我有表格视图,它显示设备名称、UUID、RSSI 和位置
我的问题是我从设备获取实时值,但这些值没有在表视图单元格中更新。
需要实时更新表视图数据
值得一提的是,我添加了 5 秒钟的复习,但仍然不起作用
我已经把我的代码打碎了。有人请帮我解决这个问题
import UIKit
import CoreBluetooth
import Combine
class DeviceListViewController: UIViewController, BluetoothManagerDelegate, UITableViewDelegate, UITableViewDataSource, CBCentralManagerDelegate {
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var strongestRSSILabel: UILabel!
var bluetoothManager: BluetoothManager!
var centralManager: CBCentralManager!
var discoveredDevices: [CBPeripheral] = []
var rssiValues: [CBPeripheral: NSNumber] = [:]
var rssiValue: Int = 0
var rssiUpdateTimer: Timer?
var deviceInfoArray: [DeviceInfo] = []
@Published var strongestRSSI: NSNumber?
var strongestPeripheral: CBPeripheral?
let deviceLocations: [String: String] = [
"00000534": "Office room",
"00000523": "Reception",
"00000525": "Lunch room"
]
private var observation: AnyCancellable?
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
centralManager = CBCentralManager(delegate: self, queue: nil)
bluetoothManager = BluetoothManager()
bluetoothManager.delegate = self
bluetoothManager.startScanning()
observation = $strongestRSSI
.sink { [weak self] newValue in
self?.tableView.reloadData()
}
refreshTableView()
rssiUpdateTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(refreshTableView), userInfo: nil, repeats: true)
RunLoop.current.add(rssiUpdateTimer!, forMode: .common)
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if central.state == .poweredOn {
// Start scanning for peripheral devices with RSSI values
central.scanForPeripherals(withServices: nil, options: nil)
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
// Update the RSSI value whenever a peripheral is discovered
rssiValue = RSSI.intValue
// You may want to update your data source here as well
}
@objc func refreshTableView() {
DispatchQueue.main.async {
self.filterDiscoveredDevices()
self.filterDiscoveredDevicesRSSI()
// Check if strongestRSSI has changed and the strongestPeripheral is available
if let strongestRSSI = self.strongestRSSI,
let strongestPeripheral = self.strongestPeripheral,
let indexPath = self.indexPathForPeripheral(strongestPeripheral) {
let cell = self.tableView.cellForRow(at: indexPath) as? DeviceTableViewCell
cell?.rssiLabel?.text = "RSSI: \(strongestRSSI)"
}
self.tableView.reloadData()
print("Table view refreshed ======================================== HHHH")
}
}
// Function to find the IndexPath for a given peripheral
private func indexPathForPeripheral(_ peripheral: CBPeripheral) -> IndexPath? {
for (index, device) in discoveredDevices.enumerated() {
if device === peripheral {
return IndexPath(row: index, section: 0)
}
}
return nil
}
func filterDiscoveredDevices() {
discoveredDevices = discoveredDevices.filter { peripheral in
if let name = peripheral.name {
return ["00000534", "00000523", "00000525"].contains(name)
}
return false
}
}
func filterDiscoveredDevicesRSSI() {
// Filter the discovered devices based on the names
let filteredDevices = discoveredDevices.filter { peripheral in
if let name = peripheral.name {
return ["00000534", "00000523", "00000525"].contains(name)
}
return false
}
// Fetch RSSI values for the filtered devices
for peripheral in filteredDevices {
peripheral.readRSSI()
}
// Determine the strongest RSSI value among the filtered devices
var strongestRSSI: NSNumber?
var strongestLocation: String?
for peripheral in filteredDevices {
if let rssi = rssiValues[peripheral] {
if strongestRSSI == nil || rssi.intValue > strongestRSSI!.intValue {
strongestRSSI = rssi
strongestLocation = deviceLocations[peripheral.name ?? ""]
}
}
}
// Update strongestRSSI using @Published
self.strongestRSSI = strongestRSSI
// Update the UILabel with the combined label
var combinedLabelText = "Strongest RSSI: N/A"
if let strongestRSSI = strongestRSSI, let strongestLocation = strongestLocation {
combinedLabelText = "Strongest RSSI: \(strongestRSSI), Location: \(strongestLocation)"
}
strongestRSSILabel.text = combinedLabelText
}
// Implement BluetoothManagerDelegate methods
func bluetoothManager(_ manager: BluetoothManager, didDiscoverPeripheral peripheral: CBPeripheral, withRSSI RSSI: NSNumber) {
if !discoveredDevices.contains(peripheral) {
rssiValues[peripheral] = RSSI
discoveredDevices.append(peripheral)
filterDiscoveredDevices()
filterDiscoveredDevicesRSSI()
tableView.reloadData()
// Check if the RSSI is stronger than the current strongest RSSI
if strongestRSSI == nil || RSSI.intValue > strongestRSSI!.intValue {
strongestRSSI = RSSI
strongestPeripheral = peripheral
}
}
}
func refreshRSSIValues() {
for peripheral in discoveredDevices {
peripheral.readRSSI()
}
}
func bluetoothManager(_ manager: BluetoothManager, didStartAdvertisingPeripheral success: Bool) {
if success {
// Start advertising
} else {
// Handle advertising failure
}
}
// Implement UITableViewDelegate and UITableViewDataSource methods
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return discoveredDevices.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DeviceCell", for: indexPath) as! DeviceTableViewCell
let peripheral = discoveredDevices[indexPath.row]
cell.nameLabel?.text = "Device Name: \(peripheral.name ?? "Unnamed Device")"
cell.uuidLabel?.text = "UUID: \(peripheral.identifier.uuidString)"
// Get the RSSI value from the dictionary
if let rssi = rssiValues[peripheral] {
cell.rssiLabel?.text = "RSSI: \(rssi)"
} else {
cell.rssiLabel?.text = "RSSI: N/A"
}
if let location = deviceLocations[peripheral.name ?? "Device Name"] {
cell.locationLabel?.text = "Location: \(location)"
} else {
cell.locationLabel?.text = "Location: N/A"
}
return cell
}
}
答: 暂无答案
评论