Fix blank message row and API misuse warnings

- Fix blank row appearing when peer disconnects by ensuring display names are never empty
- Add validation to prevent system messages with empty content from being displayed
- Fix API MISUSE warnings by adding connection state checks before writing to peripherals
- Improve write queue processing with additional safety checks
- Update activity tracking when processing queued writes

These fixes address UI glitches and improve Bluetooth reliability.
This commit is contained in:
jack
2025-07-23 21:02:51 +02:00
parent a33ba1678b
commit 391c80ef14
2 changed files with 38 additions and 14 deletions
+25 -9
View File
@@ -201,17 +201,26 @@ class BluetoothMeshService: NSObject {
private func writeToPeripheral(_ data: Data, peripheral: CBPeripheral, characteristic: CBCharacteristic, peerID: String? = nil) {
let peripheralID = peripheral.identifier.uuidString
if peripheral.state == .connected {
// Direct write if connected
let writeType: CBCharacteristicWriteType = data.count > 512 ? .withResponse : .withoutResponse
peripheral.writeValue(data, for: characteristic, type: writeType)
// Update activity tracking
updatePeripheralActivity(peripheralID)
} else {
// Double check the peripheral state to avoid API misuse
guard peripheral.state == .connected else {
// Queue write for disconnected peripheral
queueWrite(data: data, peripheralID: peripheralID, peerID: peerID)
return
}
// Verify characteristic is valid and writable
guard characteristic.properties.contains(.write) || characteristic.properties.contains(.writeWithoutResponse) else {
SecureLogger.log("Characteristic does not support writing for peripheral \(peripheralID)",
category: SecureLogger.session, level: .warning)
return
}
// Direct write if connected
let writeType: CBCharacteristicWriteType = data.count > 512 ? .withResponse : .withoutResponse
peripheral.writeValue(data, for: characteristic, type: writeType)
// Update activity tracking
updatePeripheralActivity(peripheralID)
}
private func queueWrite(data: Data, peripheralID: String, peerID: String?) {
@@ -263,10 +272,17 @@ class BluetoothMeshService: NSObject {
// Process queued writes with small delay between them
for (index, queuedWrite) in queue.enumerated() {
DispatchQueue.main.asyncAfter(deadline: .now() + Double(index) * 0.01) { [weak self] in
guard peripheral.state == .connected else { return }
guard let self = self,
peripheral.state == .connected,
characteristic.properties.contains(.write) || characteristic.properties.contains(.writeWithoutResponse) else {
return
}
let writeType: CBCharacteristicWriteType = queuedWrite.data.count > 512 ? .withResponse : .withoutResponse
peripheral.writeValue(queuedWrite.data, for: characteristic, type: writeType)
// Update activity tracking
self.updatePeripheralActivity(peripheralID)
}
}
}
+13 -5
View File
@@ -1953,9 +1953,11 @@ extension ChatViewModel: BitchatDelegate {
}
}
} else {
// System message - always add
messages.append(finalMessage)
messages.sort { $0.timestamp < $1.timestamp }
// System message - check for empty content before adding
if !finalMessage.content.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
messages.append(finalMessage)
messages.sort { $0.timestamp < $1.timestamp }
}
}
}
@@ -2067,9 +2069,12 @@ extension ChatViewModel: BitchatDelegate {
// Resolve nickname using helper
let displayName = resolveNickname(for: peerID)
// Ensure we have a valid display name
let finalDisplayName = displayName.isEmpty ? "peer" : displayName
let systemMessage = BitchatMessage(
sender: "system",
content: "\(displayName) connected",
content: "\(finalDisplayName) connected",
timestamp: Date(),
isRelay: false,
originalSender: nil
@@ -2098,9 +2103,12 @@ extension ChatViewModel: BitchatDelegate {
// Resolve nickname using helper
let displayName = resolveNickname(for: peerID)
// Ensure we have a valid display name
let finalDisplayName = displayName.isEmpty ? "peer" : displayName
let systemMessage = BitchatMessage(
sender: "system",
content: "\(displayName) disconnected",
content: "\(finalDisplayName) disconnected",
timestamp: Date(),
isRelay: false,
originalSender: nil