Refactor BLEManager.context setting on all the views, and just do that at the app root instead

This commit is contained in:
Blake McAnally 2024-07-14 00:42:11 -05:00
parent 3a746af27e
commit fbf059be6a
42 changed files with 90 additions and 221 deletions

View file

@ -12,9 +12,9 @@ import OSLog
// ---------------------------------------------------------------------------------------
class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate, ObservableObject {
var appState: AppState
let appState: AppState
var context: NSManagedObjectContext?
let context: NSManagedObjectContext
private var centralManager: CBCentralManager!
@ -54,11 +54,14 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let LOGRADIO_UUID = CBUUID(string: "0x5a3d6e49-06e6-4423-9944-e9de8cdf9547")
// MARK: init
init(
appState: AppState
appState: AppState,
context: NSManagedObjectContext
) {
self.appState = appState
self.context = context
self.lastConnectionError = ""
self.connectedVersion = "0.0.0"
super.init()
@ -445,11 +448,11 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
success = true
let traceRoute = TraceRouteEntity(context: context!)
let traceRoute = TraceRouteEntity(context: context)
let nodes = NodeInfoEntity.fetchRequest()
nodes.predicate = NSPredicate(format: "num IN %@", [destNum, self.connectedPeripheral.num])
do {
let fetchedNodes = try context!.fetch(nodes)
let fetchedNodes = try context.fetch(nodes)
let receivingNode = fetchedNodes.first(where: { $0.num == destNum })
let connectedNode = fetchedNodes.first(where: { $0.num == self.connectedPeripheral.num })
traceRoute.id = Int64(meshPacket.id)
@ -465,10 +468,10 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
}
}
do {
try context!.save()
try context.save()
Logger.data.info("💾 Saved TraceRoute sent to node: \(String(receivingNode?.user?.longName ?? "unknown".localized), privacy: .public)")
} catch {
context!.rollback()
context.rollback()
let nsError = error as NSError
Logger.data.error("Error Updating Core Data BluetoothConfigEntity: \(nsError, privacy: .public)")
}
@ -647,13 +650,10 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
// Handle Any local only packets we get over BLE
case .unknownApp:
var nowKnown = false
guard let ctx = context else {
return
}
// MyInfo from initial connection
if decodedInfo.myInfo.isInitialized && decodedInfo.myInfo.myNodeNum > 0 {
let myInfo = myInfoPacket(myInfo: decodedInfo.myInfo, peripheralId: self.connectedPeripheral.id, context: ctx)
let myInfo = myInfoPacket(myInfo: decodedInfo.myInfo, peripheralId: self.connectedPeripheral.id, context: context)
if myInfo != nil {
UserDefaults.preferredPeripheralNum = Int(myInfo?.myNodeNum ?? 0)
@ -671,9 +671,9 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
do {
disconnectPeripheral(reconnect: false)
try container.restorePersistentStore(from: databasePath)
context?.refreshAllObjects()
context.refreshAllObjects()
let request = MyInfoEntity.fetchRequest()
try context?.fetch(request)
try context.fetch(request)
UserDefaults.preferredPeripheralNum = Int(myInfo?.myNodeNum ?? 0)
connectTo(peripheral: peripheral)
Logger.data.notice("🗂️ Restored Core data for /\(UserDefaults.preferredPeripheralNum, privacy: .public)")
@ -689,7 +689,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
// NodeInfo
if decodedInfo.nodeInfo.num > 0 {
nowKnown = true
if let nodeInfo = nodeInfoPacket(nodeInfo: decodedInfo.nodeInfo, channel: decodedInfo.packet.channel, context: ctx) {
if let nodeInfo = nodeInfoPacket(nodeInfo: decodedInfo.nodeInfo, channel: decodedInfo.packet.channel, context: context) {
if self.connectedPeripheral != nil && self.connectedPeripheral.num == nodeInfo.num {
if nodeInfo.user != nil {
connectedPeripheral.shortName = nodeInfo.user?.shortName ?? "?"
@ -701,17 +701,17 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
// Channels
if decodedInfo.channel.isInitialized && connectedPeripheral != nil {
nowKnown = true
channelPacket(channel: decodedInfo.channel, fromNum: Int64(truncatingIfNeeded: connectedPeripheral.num), context: ctx)
channelPacket(channel: decodedInfo.channel, fromNum: Int64(truncatingIfNeeded: connectedPeripheral.num), context: context)
}
// Config
if decodedInfo.config.isInitialized && !invalidVersion && connectedPeripheral != nil {
nowKnown = true
localConfig(config: decodedInfo.config, context: ctx, nodeNum: Int64(truncatingIfNeeded: self.connectedPeripheral.num), nodeLongName: self.connectedPeripheral.longName)
localConfig(config: decodedInfo.config, context: context, nodeNum: Int64(truncatingIfNeeded: self.connectedPeripheral.num), nodeLongName: self.connectedPeripheral.longName)
}
// Module Config
if decodedInfo.moduleConfig.isInitialized && !invalidVersion && self.connectedPeripheral?.num != 0 {
nowKnown = true
moduleConfig(config: decodedInfo.moduleConfig, context: ctx, nodeNum: Int64(truncatingIfNeeded: self.connectedPeripheral?.num ?? 0), nodeLongName: self.connectedPeripheral.longName)
moduleConfig(config: decodedInfo.moduleConfig, context: context, nodeNum: Int64(truncatingIfNeeded: self.connectedPeripheral?.num ?? 0), nodeLongName: self.connectedPeripheral.longName)
if decodedInfo.moduleConfig.payloadVariant == ModuleConfig.OneOf_PayloadVariant.cannedMessage(decodedInfo.moduleConfig.cannedMessage) {
if decodedInfo.moduleConfig.cannedMessage.enabled {
_ = self.getCannedMessageModuleMessages(destNum: self.connectedPeripheral.num, wantResponse: true)
@ -721,7 +721,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
// Device Metadata
if decodedInfo.metadata.firmwareVersion.count > 0 && !invalidVersion {
nowKnown = true
deviceMetadataPacket(metadata: decodedInfo.metadata, fromNum: connectedPeripheral.num, context: ctx)
deviceMetadataPacket(metadata: decodedInfo.metadata, fromNum: connectedPeripheral.num, context: context)
connectedPeripheral.firmwareVersion = decodedInfo.metadata.firmwareVersion
let lastDotIndex = decodedInfo.metadata.firmwareVersion.lastIndex(of: ".")
if lastDotIndex == nil {
@ -747,28 +747,28 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
packet: decodedInfo.packet,
wantRangeTestPackets: wantRangeTestPackets,
connectedNode: (self.connectedPeripheral != nil ? connectedPeripheral.num : 0),
context: context!,
context: context,
appState: appState
)
case .remoteHardwareApp:
MeshLogger.log("🕸️ MESH PACKET received for Remote Hardware App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure")")
case .positionApp:
upsertPositionPacket(packet: decodedInfo.packet, context: context!)
upsertPositionPacket(packet: decodedInfo.packet, context: context)
case .waypointApp:
waypointPacket(packet: decodedInfo.packet, context: context!)
waypointPacket(packet: decodedInfo.packet, context: context)
case .nodeinfoApp:
if !invalidVersion { upsertNodeInfoPacket(packet: decodedInfo.packet, context: context!) }
if !invalidVersion { upsertNodeInfoPacket(packet: decodedInfo.packet, context: context) }
case .routingApp:
if !invalidVersion { routingPacket(packet: decodedInfo.packet, connectedNodeNum: self.connectedPeripheral.num, context: context!) }
if !invalidVersion { routingPacket(packet: decodedInfo.packet, connectedNodeNum: self.connectedPeripheral.num, context: context) }
case .adminApp:
adminAppPacket(packet: decodedInfo.packet, context: context!)
adminAppPacket(packet: decodedInfo.packet, context: context)
case .replyApp:
MeshLogger.log("🕸️ MESH PACKET received for Reply App handling as a text message")
textMessageAppPacket(
packet: decodedInfo.packet,
wantRangeTestPackets: wantRangeTestPackets,
connectedNode: (self.connectedPeripheral != nil ? connectedPeripheral.num : 0),
context: context!,
context: context,
appState: appState
)
case .ipTunnelApp:
@ -779,7 +779,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
MeshLogger.log("🕸️ MESH PACKET received for Serial App UNHANDLED UNHANDLED")
case .storeForwardApp:
if wantStoreAndForwardPackets {
storeAndForwardPacket(packet: decodedInfo.packet, connectedNodeNum: (self.connectedPeripheral != nil ? connectedPeripheral.num : 0), context: context!)
storeAndForwardPacket(packet: decodedInfo.packet, connectedNodeNum: (self.connectedPeripheral != nil ? connectedPeripheral.num : 0), context: context)
} else {
MeshLogger.log("🕸️ MESH PACKET received for Store and Forward App - Store and Forward is disabled.")
}
@ -789,14 +789,14 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
packet: decodedInfo.packet,
wantRangeTestPackets: true,
connectedNode: (self.connectedPeripheral != nil ? connectedPeripheral.num : 0),
context: context!,
context: context,
appState: appState
)
} else {
MeshLogger.log("🕸️ MESH PACKET received for Range Test App Range testing is disabled.")
}
case .telemetryApp:
if !invalidVersion { telemetryPacket(packet: decodedInfo.packet, connectedNode: (self.connectedPeripheral != nil ? connectedPeripheral.num : 0), context: context!) }
if !invalidVersion { telemetryPacket(packet: decodedInfo.packet, connectedNode: (self.connectedPeripheral != nil ? connectedPeripheral.num : 0), context: context) }
case .textMessageCompressedApp:
// MeshLogger.log("🕸 MESH PACKET received for Text Message Compressed App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure")")
MeshLogger.log("🕸️ MESH PACKET received for Text Message Compressed App UNHANDLED")
@ -817,7 +817,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
MeshLogger.log("🕸️ MESH PACKET received for Audio App UNHANDLED UNHANDLED")
case .tracerouteApp:
if let routingMessage = try? RouteDiscovery(serializedData: decodedInfo.packet.decoded.payload) {
let traceRoute = getTraceRoute(id: Int64(decodedInfo.packet.decoded.requestID), context: context!)
let traceRoute = getTraceRoute(id: Int64(decodedInfo.packet.decoded.requestID), context: context)
traceRoute?.response = true
traceRoute?.route = routingMessage.route
if routingMessage.route.count == 0 {
@ -828,11 +828,11 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
var routeString = "You --> "
var hopNodes: [TraceRouteHopEntity] = []
for node in routingMessage.route {
var hopNode = getNodeInfo(id: Int64(node), context: context!)
var hopNode = getNodeInfo(id: Int64(node), context: context)
if hopNode == nil && hopNode?.num ?? 0 > 0 {
hopNode = createNodeInfo(num: Int64(node), context: context!)
hopNode = createNodeInfo(num: Int64(node), context: context)
}
let traceRouteHop = TraceRouteHopEntity(context: context!)
let traceRouteHop = TraceRouteHopEntity(context: context)
traceRouteHop.time = Date()
if hopNode?.hasPositions ?? false {
traceRoute?.hasPositions = true
@ -860,10 +860,10 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
traceRoute?.routeText = routeString
traceRoute?.hops = NSOrderedSet(array: hopNodes)
do {
try context!.save()
try context.save()
Logger.data.info("💾 Saved Trace Route")
} catch {
context!.rollback()
context.rollback()
let nsError = error as NSError
Logger.data.error("Error Updating Core Data TraceRouteHOp: \(nsError, privacy: .public)")
}
@ -877,7 +877,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
MeshLogger.log("🕸️ MESH PACKET received for Neighbor Info App UNHANDLED \(neighborInfo)")
}
case .paxcounterApp:
paxCounterPacket(packet: decodedInfo.packet, context: context!)
paxCounterPacket(packet: decodedInfo.packet, context: context)
case .mapReportApp:
MeshLogger.log("🕸️ MESH PACKET received Map Report App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure")")
case .UNRECOGNIZED:
@ -904,7 +904,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(connectedPeripheral.num))
do {
let fetchedNodeInfo = try context?.fetch(fetchNodeInfoRequest) ?? []
let fetchedNodeInfo = try context.fetch(fetchNodeInfoRequest) ?? []
if fetchedNodeInfo.count == 1 {
// Subscribe to Mqtt Client Proxy if enabled
if fetchedNodeInfo[0].mqttConfig != nil && fetchedNodeInfo[0].mqttConfig?.enabled ?? false && fetchedNodeInfo[0].mqttConfig?.proxyToClientEnabled ?? false {
@ -980,7 +980,6 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
success = false
} else {
guard let context else { return false }
let fromUserNum: Int64 = self.connectedPeripheral.num
let messageUsers = UserEntity.fetchRequest()
@ -1101,7 +1100,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected {
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
success = true
let wayPointEntity = getWaypoint(id: Int64(waypoint.id), context: context!)
let wayPointEntity = getWaypoint(id: Int64(waypoint.id), context: context)
wayPointEntity.id = Int64(waypoint.id)
wayPointEntity.name = waypoint.name.count >= 1 ? waypoint.name : "Dropped Pin"
wayPointEntity.longDescription = waypoint.description_p
@ -1124,10 +1123,10 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
wayPointEntity.lastUpdated = Date()
}
do {
try context!.save()
try context.save()
Logger.data.info("💾 Updated Waypoint from Waypoint App Packet From: \(fromNodeNum.toHex(), privacy: .public)")
} catch {
context!.rollback()
context.rollback()
let nsError = error as NSError
Logger.data.error("Error Saving NodeInfoEntity from WAYPOINT_APP \(nsError, privacy: .public)")
}
@ -1526,7 +1525,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let fetchMyInfoRequest = MyInfoEntity.fetchRequest()
fetchMyInfoRequest.predicate = NSPredicate(format: "myNodeNum == %lld", Int64(connectedPeripheral.num))
do {
let fetchedMyInfo = try context?.fetch(fetchMyInfoRequest) ?? []
let fetchedMyInfo = try context.fetch(fetchMyInfoRequest) ?? []
if fetchedMyInfo.count == 1 {
i = Int32(fetchedMyInfo[0].channels?.count ?? -1)
myInfo = fetchedMyInfo[0]
@ -1678,12 +1677,12 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected {
do {
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
context!.delete(node.user!)
context!.delete(node)
try context!.save()
context.delete(node.user!)
context.delete(node)
try context.save()
return true
} catch {
context!.rollback()
context.rollback()
let nsError = error as NSError
Logger.data.error("🚫 Error deleting node from core data: \(nsError)")
}
@ -1792,7 +1791,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let messageDescription = "🛟 Saved Bluetooth Config for \(toUser.longName ?? "unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertBluetoothConfigPacket(config: config, nodeNum: toUser.num, context: context!)
upsertBluetoothConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
}
@ -1820,7 +1819,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Device Config for \(toUser.longName ?? "unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertDeviceConfigPacket(config: config, nodeNum: toUser.num, context: context!)
upsertDeviceConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
}
return 0
@ -1847,7 +1846,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
meshPacket.decoded = dataMessage
let messageDescription = "🛟 Saved Display Config for \(toUser.longName ?? "unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertDisplayConfigPacket(config: config, nodeNum: toUser.num, context: context!)
upsertDisplayConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
}
return 0
@ -1874,7 +1873,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let messageDescription = "🛟 Saved LoRa Config for \(toUser.longName ?? "unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertLoRaConfigPacket(config: config, nodeNum: toUser.num, context: context!)
upsertLoRaConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
}
@ -1905,7 +1904,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let messageDescription = "🛟 Saved Position Config for \(toUser.longName ?? "unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertPositionConfigPacket(config: config, nodeNum: toUser.num, context: context!)
upsertPositionConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
}
@ -1936,7 +1935,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let messageDescription = "🛟 Saved Power Config for \(toUser.longName ?? "unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertPowerConfigPacket(config: config, nodeNum: toUser.num, context: context!)
upsertPowerConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
}
@ -1967,7 +1966,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let messageDescription = "🛟 Saved Network Config for \(toUser.longName ?? "unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertNetworkConfigPacket(config: config, nodeNum: toUser.num, context: context!)
upsertNetworkConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
}
@ -1997,7 +1996,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let messageDescription = "🛟 Saved Ambient Lighting Module Config for \(toUser.longName ?? "unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertAmbientLightingModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
upsertAmbientLightingModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
}
@ -2027,7 +2026,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let messageDescription = "🛟 Saved Canned Message Module Config for \(toUser.longName ?? "unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertCannedMessagesModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
upsertCannedMessagesModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
}
@ -2088,7 +2087,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let messageDescription = "🛟 Saved Detection Sensor Module Config for \(toUser.longName ?? "unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertDetectionSensorModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
upsertDetectionSensorModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
}
return 0
@ -2117,7 +2116,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let messageDescription = "🛟 Saved External Notification Module Config for \(toUser.longName ?? "unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertExternalNotificationModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
upsertExternalNotificationModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
}
return 0
@ -2146,7 +2145,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let messageDescription = "🛟 Saved PAX Counter Module Config for \(toUser.longName ?? "unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertPaxCounterModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
upsertPaxCounterModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
}
@ -2176,7 +2175,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let messageDescription = "🛟 Saved RTTTL Ringtone Config for \(toUser.longName ?? "unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertRtttlConfigPacket(ringtone: ringtone, nodeNum: toUser.num, context: context!)
upsertRtttlConfigPacket(ringtone: ringtone, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
}
@ -2207,7 +2206,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let messageDescription = "🛟 Saved MQTT Config for \(toUser.longName ?? "unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertMqttModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
upsertMqttModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
}
return 0
@ -2236,7 +2235,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let messageDescription = "🛟 Saved Range Test Module Config for \(toUser.longName ?? "unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertRangeTestModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
upsertRangeTestModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
}
@ -2266,7 +2265,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let messageDescription = "🛟 Saved Serial Module Config for \(toUser.longName ?? "unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertSerialModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
upsertSerialModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
}
return 0
@ -2295,7 +2294,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let messageDescription = "🛟 Saved Store & Forward Module Config for \(toUser.longName ?? "unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertStoreForwardModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
upsertStoreForwardModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
}
return 0
@ -2324,7 +2323,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
let messageDescription = "Saved Telemetry Module Config for \(toUser.longName ?? "unknown".localized)"
if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) {
upsertTelemetryModuleConfigPacket(config: config, nodeNum: toUser.num, context: context!)
upsertTelemetryModuleConfigPacket(config: config, nodeNum: toUser.num, context: context)
return Int64(meshPacket.id)
}
return 0
@ -3106,7 +3105,6 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
}
public func tryClearExistingChannels() {
guard let context else { return }
// Before we get started delete the existing channels from the myNodeInfo
let fetchMyInfoRequest = MyInfoEntity.fetchRequest()
fetchMyInfoRequest.predicate = NSPredicate(format: "myNodeNum == %lld", Int64(connectedPeripheral.num))

View file

@ -35,7 +35,10 @@ struct MeshtasticAppleApp: App {
)
self._appState = ObservedObject(wrappedValue: appState)
self.bleManager = BLEManager(appState: appState)
self.bleManager = BLEManager(
appState: appState,
context: persistenceController.container.viewContext
)
self.persistenceController = persistenceController
// Wire up router
@ -45,7 +48,8 @@ struct MeshtasticAppleApp: App {
var body: some Scene {
WindowGroup {
ContentView(
appState: appState
appState: appState,
router: appState.router
)
.environment(\.managedObjectContext, persistenceController.container.viewContext)
.environmentObject(appState)

View file

@ -2,6 +2,7 @@ import CoreData
import OSLog
import SwiftUI
@MainActor
class Router: ObservableObject {
@Published

View file

@ -323,11 +323,6 @@ struct Connect: View {
}
}
}
.onAppear(perform: {
if self.bleManager.context == nil {
self.bleManager.context = context
}
})
}
#if canImport(ActivityKit)
func startNodeActivity() {

View file

@ -8,20 +8,19 @@ import SwiftUI
struct ContentView: View {
@ObservedObject
var appState: AppState
@ObservedObject
var router: Router
private var tabBinding: Binding<NavigationState.Tab> {
Binding(
var body: some View {
TabView(selection: Binding(
get: {
appState.router.navigationState.tab
},
set: { newValue in
appState.router.navigationState.tab = newValue
}
)
}
var body: some View {
TabView(selection: tabBinding) {
)) {
Messages(
router: appState.router,
unreadChannelMessages: $appState.unreadChannelMessages,

View file

@ -122,7 +122,7 @@ struct WaypointFormMapKit: View {
// Loading a waypoint from edit
if coordinate.waypointId > 0 {
newWaypoint.id = UInt32(coordinate.waypointId)
let waypoint = getWaypoint(id: Int64(coordinate.waypointId), context: bleManager.context!)
let waypoint = getWaypoint(id: Int64(coordinate.waypointId), context: bleManager.context)
newWaypoint.latitudeI = waypoint.latitudeI
newWaypoint.longitudeI = waypoint.longitudeI
} else {
@ -179,12 +179,12 @@ struct WaypointFormMapKit: View {
Menu {
Button("For me", action: {
let waypoint = getWaypoint(id: Int64(coordinate.waypointId), context: bleManager.context!)
bleManager.context!.delete(waypoint)
let waypoint = getWaypoint(id: Int64(coordinate.waypointId), context: bleManager.context)
bleManager.context.delete(waypoint)
do {
try bleManager.context!.save()
try bleManager.context.save()
} catch {
bleManager.context!.rollback()
bleManager.context.rollback()
}
dismiss() })
Button("For everyone", action: {
@ -230,7 +230,7 @@ struct WaypointFormMapKit: View {
}
.onAppear {
if coordinate.waypointId > 0 {
let waypoint = getWaypoint(id: Int64(coordinate.waypointId), context: bleManager.context!)
let waypoint = getWaypoint(id: Int64(coordinate.waypointId), context: bleManager.context)
name = waypoint.name ?? "Dropped Pin"
description = waypoint.longDescription ?? ""
icon = String(UnicodeScalar(Int(waypoint.icon)) ?? "📍")

View file

@ -146,11 +146,6 @@ struct ChannelList: View {
Text("delete")
}
}
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
}
}
.padding([.top, .bottom])

View file

@ -129,9 +129,6 @@ struct ChannelMessageList: View {
.padding([.top])
.scrollDismissesKeyboard(.immediately)
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
if channel.allPrivateMessages.count > 0 {
scrollView.scrollTo(channel.allPrivateMessages.last!.messageId)
}

View file

@ -88,10 +88,6 @@ struct Messages: View {
.navigationBarTitleDisplayMode(.large)
.navigationBarItems(leading: MeshtasticLogo())
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
let nodeId = Int64(UserDefaults.preferredPeripheralNum)
if nodeId > 0 {
node = getNodeInfo(id: nodeId, context: context)
@ -113,7 +109,7 @@ struct Messages: View {
}
}
} detail: {
}
}
}

View file

@ -209,9 +209,6 @@ struct UserList: View {
userSelection = users.first(where: { $0.num == newUserNum })
}
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
searchUserList()
}
.safeAreaInset(edge: .bottom, alignment: .trailing) {

View file

@ -115,9 +115,6 @@ struct UserMessageList: View {
.padding([.top])
.scrollDismissesKeyboard(.immediately)
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
if user.messageList.count > 0 {
scrollView.scrollTo(user.messageList.last!.messageId)
}

View file

@ -124,11 +124,6 @@ struct DetectionSensorLog: View {
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
.fileExporter(
isPresented: $isExporting,
document: CsvDocument(emptyCsv: exportString),

View file

@ -222,11 +222,6 @@ struct DeviceMetricsLog: View {
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
.fileExporter(
isPresented: $isExporting,
document: CsvDocument(emptyCsv: exportString),

View file

@ -199,11 +199,6 @@ struct EnvironmentMetricsLog: View {
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
.fileExporter(
isPresented: $isExporting,
document: CsvDocument(emptyCsv: exportString),

View file

@ -184,11 +184,11 @@ struct WaypointForm: View {
Menu {
Button("For me", action: {
bleManager.context!.delete(waypoint)
bleManager.context.delete(waypoint)
do {
try bleManager.context!.save()
try bleManager.context.save()
} catch {
bleManager.context!.rollback()
bleManager.context.rollback()
}
dismiss() })
Button("For everyone", action: {
@ -213,11 +213,11 @@ struct WaypointForm: View {
newWaypoint.expire = UInt32(1)
if bleManager.sendWaypoint(waypoint: newWaypoint) {
bleManager.context!.delete(waypoint)
bleManager.context.delete(waypoint)
do {
try bleManager.context!.save()
try bleManager.context.save()
} catch {
bleManager.context!.rollback()
bleManager.context.rollback()
}
dismiss()
} else {
@ -351,7 +351,7 @@ struct WaypointForm: View {
}
.onAppear {
if waypoint.id > 0 {
let waypoint = getWaypoint(id: Int64(waypoint.id), context: bleManager.context!)
let waypoint = getWaypoint(id: Int64(waypoint.id), context: bleManager.context)
name = waypoint.name ?? "Dropped Pin"
description = waypoint.longDescription ?? ""
icon = String(UnicodeScalar(Int(waypoint.icon)) ?? "📍")

View file

@ -396,11 +396,6 @@ struct NodeDetail: View {
}
}
.listStyle(.insetGrouped)
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
}
}
}

View file

@ -251,10 +251,6 @@ struct NodeList: View {
}
}
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
Task {
await searchNodeList()
}

View file

@ -243,9 +243,6 @@ struct NodeMap: View {
})
.onAppear(perform: {
UIApplication.shared.isIdleTimerDisabled = true
if self.bleManager.context == nil {
self.bleManager.context = context
}
})
.onDisappear(perform: {
UIApplication.shared.isIdleTimerDisabled = false

View file

@ -209,11 +209,6 @@ struct PaxCounterLog: View {
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
.fileExporter(
isPresented: $isExporting,
document: CsvDocument(emptyCsv: exportString),

View file

@ -179,10 +179,5 @@ struct PositionLog: View {
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
}
}

View file

@ -145,10 +145,5 @@ struct TraceRouteLog: View {
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
}
}

View file

@ -103,10 +103,5 @@ struct AppSettings: View {
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
}
}

View file

@ -280,11 +280,6 @@ struct Channels: View {
ZStack {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
}
}
}

View file

@ -107,9 +107,6 @@ struct BluetoothConfig: View {
}
)
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setBluetoothValues()
// Need to request a BluetoothConfig from the remote node before allowing changes
if let connectedPeripheral = bleManager.connectedPeripheral, let node, node.bluetoothConfig == nil {

View file

@ -238,9 +238,6 @@ struct DeviceConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setDeviceValues()
// Need to request a LoRaConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.deviceConfig == nil {

View file

@ -159,9 +159,6 @@ struct DisplayConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setDisplayValues()
// Need to request a LoRaConfig from the remote node before allowing changes

View file

@ -226,9 +226,6 @@ struct LoRaConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setLoRaValues()
// Need to request a LoRaConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.loRaConfig == nil {

View file

@ -85,9 +85,6 @@ struct AmbientLightingConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setAmbientLightingConfigValue()
// Need to request a Ambient Lighting Config from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.ambientLightingConfig == nil {

View file

@ -229,9 +229,6 @@ struct CannedMessagesConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setCannedMessagesValues()
// Need to request a CannedMessagesModuleConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.cannedMessageConfig == nil {

View file

@ -185,9 +185,6 @@ struct DetectionSensorConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setDetectionSensorValues()
// Need to request a Detection Sensor Module Config from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.detectionSensorConfig == nil {

View file

@ -195,9 +195,6 @@ struct ExternalNotificationConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setExternalNotificationValues()
// Need to request a TelemetryModuleConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.externalNotificationConfig == nil {

View file

@ -357,9 +357,6 @@ struct MQTTConfig: View {
}
}
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setMqttValues()
// Need to request a TelemetryModuleConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.mqttConfig == nil {

View file

@ -58,10 +58,6 @@ struct PaxCounterConfig: View {
)
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setPaxValues()
// Need to request a PAX Counter module config from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.paxCounterConfig == nil {

View file

@ -77,9 +77,6 @@ struct RangeTestConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setRangeTestValues()
// Need to request a RangeTestModule Config from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.rangeTestConfig == nil {

View file

@ -67,9 +67,6 @@ struct RtttlConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setRtttLConfigValue()
// Need to request a Rtttl Config from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && (node?.rtttlConfig == nil || node?.rtttlConfig?.ringtone?.count ?? 0 == 0) {

View file

@ -133,9 +133,6 @@ struct SerialConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setSerialValues()
// Need to request a SerialModuleConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.serialConfig == nil {

View file

@ -142,10 +142,6 @@ struct StoreForwardConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
// Need to request a Detection Sensor Module Config from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.storeForwardConfig == nil {
Logger.mesh.debug("empty store and forward module config")

View file

@ -130,9 +130,6 @@ struct TelemetryConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setTelemetryValues()
// Need to request a TelemetryModuleConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.telemetryConfig == nil {

View file

@ -114,9 +114,6 @@ struct NetworkConfig: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setNetworkValues()
// Need to request a NetworkConfig from the remote node before allowing changes
if bleManager.connectedPeripheral != nil && node?.networkConfig == nil {

View file

@ -377,9 +377,6 @@ struct PositionConfig: View {
}
)
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
setPositionValues()
supportedVersion = bleManager.connectedVersion == "0.0.0" || self.minimumVersion.compare(bleManager.connectedVersion, options: .numeric) == .orderedAscending || minimumVersion.compare(bleManager.connectedVersion, options: .numeric) == .orderedSame
// Need to request a PositionConfig from the remote node before allowing changes

View file

@ -118,10 +118,6 @@ struct PowerConfig: View {
}
}
.onAppear {
if self.bleManager.context == nil {
self.bleManager.context = context
}
Api().loadDeviceHardwareData { (hw) in
for device in hw {

View file

@ -238,7 +238,6 @@ struct ShareChannels: View {
ConnectedDevice(bluetoothOn: bleManager.isSwitchedOn, deviceConnected: bleManager.connectedPeripheral != nil, name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
})
.onAppear {
bleManager.context = context
generateChannelSet()
}
.onChange(of: includeChannel0) { _ in generateChannelSet() }