Add OSLog Redacttion attributes

This commit is contained in:
Garth Vander Houwen 2025-03-31 22:06:00 -07:00
parent 0d647616e2
commit ea39adac26
46 changed files with 154 additions and 1181 deletions

View file

@ -73,7 +73,6 @@
D93068DB2B81C85E0066FBC8 /* PowerConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = D93068DA2B81C85E0066FBC8 /* PowerConfig.swift */; };
D93068DD2B81CA820066FBC8 /* ConfigHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = D93068DC2B81CA820066FBC8 /* ConfigHeader.swift */; };
D93069082B81DF040066FBC8 /* SaveConfigButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D93069072B81DF040066FBC8 /* SaveConfigButton.swift */; };
D9BC22DB2B7DE8E2006A37D5 /* TileDownloadStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9BC22DA2B7DE8E2006A37D5 /* TileDownloadStatus.swift */; };
D9C9839D2B79CFD700BDBE6A /* TextMessageSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9C9839C2B79CFD700BDBE6A /* TextMessageSize.swift */; };
D9C983A02B79D0E800BDBE6A /* AlertButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9C9839F2B79D0E800BDBE6A /* AlertButton.swift */; };
D9C983A22B79D1A600BDBE6A /* RequestPositionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9C983A12B79D1A600BDBE6A /* RequestPositionButton.swift */; };
@ -99,7 +98,6 @@
DD2553572855B02500E55709 /* LoRaConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD2553562855B02500E55709 /* LoRaConfig.swift */; };
DD2553592855B52700E55709 /* PositionConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD2553582855B52700E55709 /* PositionConfig.swift */; };
DD268D8E2BCC90E2008073AE /* RouteEnums.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD268D8D2BCC90E2008073AE /* RouteEnums.swift */; };
DD2AD8A8296D2DF9001FF0E7 /* MapViewSwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD2AD8A7296D2DF9001FF0E7 /* MapViewSwiftUI.swift */; };
DD33DB622B3D27C7003E1EA0 /* FirmwareApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD33DB612B3D27C7003E1EA0 /* FirmwareApi.swift */; };
DD3501892852FC3B000FC853 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD3501882852FC3B000FC853 /* Settings.swift */; };
DD354FD92BD96A0B0061A25F /* IAQScale.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD354FD82BD96A0B0061A25F /* IAQScale.swift */; };
@ -153,9 +151,7 @@
DD93800E2BA74D0C008BEC06 /* ChannelForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD93800D2BA74D0C008BEC06 /* ChannelForm.swift */; };
DD94B7402ACCE3BE00DCD1D1 /* MapSettingsForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD94B73F2ACCE3BE00DCD1D1 /* MapSettingsForm.swift */; };
DD964FBD296E6B01007C176F /* EmojiOnlyTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD964FBC296E6B01007C176F /* EmojiOnlyTextField.swift */; };
DD964FBF296E76EF007C176F /* WaypointFormMapKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD964FBE296E76EF007C176F /* WaypointFormMapKit.swift */; };
DD964FC2297272AE007C176F /* WaypointEntityExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD964FC1297272AE007C176F /* WaypointEntityExtension.swift */; };
DD964FC42974767D007C176F /* MapViewFitExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD964FC32974767D007C176F /* MapViewFitExtension.swift */; };
DD964FC62975DBFD007C176F /* QueryCoreData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD964FC52975DBFD007C176F /* QueryCoreData.swift */; };
DD97E96628EFD9820056DDA4 /* MeshtasticLogo.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD97E96528EFD9820056DDA4 /* MeshtasticLogo.swift */; };
DD97E96828EFE9A00056DDA4 /* About.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD97E96728EFE9A00056DDA4 /* About.swift */; };
@ -212,8 +208,6 @@
DDDB26422AABF655003AFCB7 /* NodeListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB26412AABF655003AFCB7 /* NodeListItem.swift */; };
DDDB26442AAC0206003AFCB7 /* NodeDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB26432AAC0206003AFCB7 /* NodeDetail.swift */; };
DDDB26462AACC0B7003AFCB7 /* NodeInfoItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB26452AACC0B7003AFCB7 /* NodeInfoItem.swift */; };
DDDB26482AACD6D1003AFCB7 /* NodeMapMapkit.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB26472AACD6D1003AFCB7 /* NodeMapMapkit.swift */; };
DDDB443629F6287000EE2349 /* MapButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB443529F6287000EE2349 /* MapButtons.swift */; };
DDDB444029F79AB000EE2349 /* UserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB443F29F79AB000EE2349 /* UserDefaults.swift */; };
DDDB444229F8A88700EE2349 /* Double.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB444129F8A88700EE2349 /* Double.swift */; };
DDDB444429F8A8DD00EE2349 /* Float.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDDB444329F8A8DD00EE2349 /* Float.swift */; };
@ -344,7 +338,6 @@
D93068DC2B81CA820066FBC8 /* ConfigHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigHeader.swift; sourceTree = "<group>"; };
D93069062B81D8900066FBC8 /* MeshtasticDataModelV 27.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MeshtasticDataModelV 27.xcdatamodel"; sourceTree = "<group>"; };
D93069072B81DF040066FBC8 /* SaveConfigButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SaveConfigButton.swift; sourceTree = "<group>"; };
D9BC22DA2B7DE8E2006A37D5 /* TileDownloadStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileDownloadStatus.swift; sourceTree = "<group>"; };
D9C9839C2B79CFD700BDBE6A /* TextMessageSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextMessageSize.swift; sourceTree = "<group>"; };
D9C9839F2B79D0E800BDBE6A /* AlertButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertButton.swift; sourceTree = "<group>"; };
D9C983A12B79D1A600BDBE6A /* RequestPositionButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestPositionButton.swift; sourceTree = "<group>"; };
@ -379,7 +372,6 @@
DD268D8D2BCC90E2008073AE /* RouteEnums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RouteEnums.swift; sourceTree = "<group>"; };
DD295CE92B323ED9002CC4AC /* MeshtasticDataModelV22.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV22.xcdatamodel; sourceTree = "<group>"; };
DD2984A82C5AEF7500B1268D /* MeshtasticDataModelV 41.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MeshtasticDataModelV 41.xcdatamodel"; sourceTree = "<group>"; };
DD2AD8A7296D2DF9001FF0E7 /* MapViewSwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewSwiftUI.swift; sourceTree = "<group>"; };
DD2CC2E52ABFE04E00EDFDA7 /* MeshtasticDataModelV19.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV19.xcdatamodel; sourceTree = "<group>"; };
DD31B04D2BDC6FD30024FA63 /* MeshtasticDataModelV 36.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MeshtasticDataModelV 36.xcdatamodel"; sourceTree = "<group>"; };
DD33DB602B3D1ECC003E1EA0 /* MeshtasticDataModelV 23.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MeshtasticDataModelV 23.xcdatamodel"; sourceTree = "<group>"; };
@ -451,10 +443,8 @@
DD93800D2BA74D0C008BEC06 /* ChannelForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelForm.swift; sourceTree = "<group>"; };
DD94B73F2ACCE3BE00DCD1D1 /* MapSettingsForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapSettingsForm.swift; sourceTree = "<group>"; };
DD964FBC296E6B01007C176F /* EmojiOnlyTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiOnlyTextField.swift; sourceTree = "<group>"; };
DD964FBE296E76EF007C176F /* WaypointFormMapKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaypointFormMapKit.swift; sourceTree = "<group>"; };
DD964FC029724F6D007C176F /* MeshtasticDataModelV6.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV6.xcdatamodel; sourceTree = "<group>"; };
DD964FC1297272AE007C176F /* WaypointEntityExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaypointEntityExtension.swift; sourceTree = "<group>"; };
DD964FC32974767D007C176F /* MapViewFitExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapViewFitExtension.swift; sourceTree = "<group>"; };
DD964FC52975DBFD007C176F /* QueryCoreData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueryCoreData.swift; sourceTree = "<group>"; };
DD9681A22BBB22BE00FD2C47 /* MeshtasticDataModelV32.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV32.xcdatamodel; sourceTree = "<group>"; };
DD97E96528EFD9820056DDA4 /* MeshtasticLogo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshtasticLogo.swift; sourceTree = "<group>"; };
@ -528,9 +518,7 @@
DDDB26412AABF655003AFCB7 /* NodeListItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeListItem.swift; sourceTree = "<group>"; };
DDDB26432AAC0206003AFCB7 /* NodeDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeDetail.swift; sourceTree = "<group>"; };
DDDB26452AACC0B7003AFCB7 /* NodeInfoItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeInfoItem.swift; sourceTree = "<group>"; };
DDDB26472AACD6D1003AFCB7 /* NodeMapMapkit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeMapMapkit.swift; sourceTree = "<group>"; };
DDDB26492AAD743E003AFCB7 /* MeshtasticDataModelV18.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticDataModelV18.xcdatamodel; sourceTree = "<group>"; };
DDDB443529F6287000EE2349 /* MapButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapButtons.swift; sourceTree = "<group>"; };
DDDB443F29F79AB000EE2349 /* UserDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaults.swift; sourceTree = "<group>"; };
DDDB444129F8A88700EE2349 /* Double.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Double.swift; sourceTree = "<group>"; };
DDDB444329F8A8DD00EE2349 /* Float.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Float.swift; sourceTree = "<group>"; };
@ -702,27 +690,6 @@
path = AppIntents;
sourceTree = "<group>";
};
C9483F6B2773016700998F6B /* MapKitMap */ = {
isa = PBXGroup;
children = (
C9A7BC0E27759A6800760B50 /* Custom */,
DDDB26472AACD6D1003AFCB7 /* NodeMapMapkit.swift */,
DD964FBE296E76EF007C176F /* WaypointFormMapKit.swift */,
);
path = MapKitMap;
sourceTree = "<group>";
};
C9A7BC0E27759A6800760B50 /* Custom */ = {
isa = PBXGroup;
children = (
DD964FC32974767D007C176F /* MapViewFitExtension.swift */,
DD2AD8A7296D2DF9001FF0E7 /* MapViewSwiftUI.swift */,
DDDB443529F6287000EE2349 /* MapButtons.swift */,
D9BC22DA2B7DE8E2006A37D5 /* TileDownloadStatus.swift */,
);
path = Custom;
sourceTree = "<group>";
};
D9C9839E2B79D0C600BDBE6A /* TextMessageField */ = {
isa = PBXGroup;
children = (
@ -1023,7 +990,6 @@
isa = PBXGroup;
children = (
DD6D5A312CA1176A00ED3032 /* Layouts */,
C9483F6B2773016700998F6B /* MapKitMap */,
DDC2E18D26CE25CB0042C5E4 /* Helpers */,
DD47E3D726F2F21A00029299 /* Bluetooth */,
DDC2E18B26CE25A70042C5E4 /* Messages */,
@ -1415,11 +1381,9 @@
DD836AE726F6B38600ABCC23 /* Connect.swift in Sources */,
D93069082B81DF040066FBC8 /* SaveConfigButton.swift in Sources */,
DD5E523F298F5A9E00D21B61 /* AirQualityIndex.swift in Sources */,
DD964FBF296E76EF007C176F /* WaypointFormMapKit.swift in Sources */,
DDD5BB182C2F9C36007E03CA /* OSLogEntryLog.swift in Sources */,
DD3501892852FC3B000FC853 /* Settings.swift in Sources */,
DDDC22382BA92344002C44F1 /* MeshMapContent.swift in Sources */,
DDDB443629F6287000EE2349 /* MapButtons.swift in Sources */,
DD5D0A9C2931B9F200F7EA61 /* EthernetModes.swift in Sources */,
6DEDA55A2A957B8E00321D2E /* DetectionSensorLog.swift in Sources */,
DD798B072915928D005217CD /* ChannelMessageList.swift in Sources */,
@ -1464,7 +1428,6 @@
DD354FD92BD96A0B0061A25F /* IAQScale.swift in Sources */,
DDDB445429F8AD1600EE2349 /* Data.swift in Sources */,
DDDB26462AACC0B7003AFCB7 /* NodeInfoItem.swift in Sources */,
DD2AD8A8296D2DF9001FF0E7 /* MapViewSwiftUI.swift in Sources */,
DDE5B4042B2279A700FCDD05 /* TraceRouteLog.swift in Sources */,
DD6193792863875F00E59241 /* SerialConfig.swift in Sources */,
DDDB263F2AABEE20003AFCB7 /* NodeList.swift in Sources */,
@ -1474,7 +1437,6 @@
B399E8A42B6F486400E4488E /* RetryButton.swift in Sources */,
DDB8F4102A9EE5B400230ECE /* Messages.swift in Sources */,
233E99C32D849D7A00CC3A77 /* WeightCompactWidget.swift in Sources */,
DDDB26482AACD6D1003AFCB7 /* NodeMapMapkit.swift in Sources */,
DD4A911E2708C65400501B7E /* AppSettings.swift in Sources */,
DD1BD0F32C63C65E008C0C70 /* SecurityConfig.swift in Sources */,
DD2160AF28C5552500C17253 /* MQTTConfig.swift in Sources */,
@ -1518,7 +1480,6 @@
D93068DB2B81C85E0066FBC8 /* PowerConfig.swift in Sources */,
D93068D32B8129510066FBC8 /* MessageContextMenuItems.swift in Sources */,
DD8EBF43285058FA00426DCA /* DisplayConfig.swift in Sources */,
DD964FC42974767D007C176F /* MapViewFitExtension.swift in Sources */,
BCE2D3C72C7B0D0A008E6199 /* ShortcutsProvider.swift in Sources */,
DD47E3D626F17ED900029299 /* CircleText.swift in Sources */,
DDC2E18F26CE25FE0042C5E4 /* ContentView.swift in Sources */,
@ -1537,7 +1498,6 @@
D93068DD2B81CA820066FBC8 /* ConfigHeader.swift in Sources */,
251926872C3BAE2200249DF5 /* NodeAlertsButton.swift in Sources */,
DDA1C48E28DB49D3009933EC /* ChannelRoles.swift in Sources */,
D9BC22DB2B7DE8E2006A37D5 /* TileDownloadStatus.swift in Sources */,
DDD5BB092C285DDC007E03CA /* AppLog.swift in Sources */,
BC5EBA3C2D002A2000C442FF /* MessageNodeIntent.swift in Sources */,
DD8ED9C8289CE4B900B3B0AB /* RoutingError.swift in Sources */,

View file

@ -16,7 +16,7 @@ class AppIntentErrors {
var localizedStringResource: LocalizedStringResource {
switch self {
case let .message(message):
Logger.services.error("App Intent: \(message)")
Logger.services.error("App Intent: \(message,privacy: .public)")
return "Error: \(message)"
case .notConnected:
Logger.services.error("App Intent: No Connected Node")

View file

@ -119,7 +119,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
self.isConnected = false
self.isConnecting = false
self.lastConnectionError = "🚨 " + String.localizedStringWithFormat("Connection failed after %d attempts to connect to %@. You may need to forget your device under Settings > Bluetooth.".localized, timeoutTimerCount, name)
Logger.services.error("\(self.lastConnectionError)")
Logger.services.error("\(self.lastConnectionError, privacy: .public)")
self.timeoutTimerCount = 0
self.startScanning()
} else {
@ -295,7 +295,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
} else {
// Disconnected without error which indicates user intent to disconnect
// Happens when swiping to disconnect
Logger.services.info(" [BLE] Disconnected: \(peripheral.name ?? "Unknown".localized, privacy: .public): \(String(describing: "User Initiated Disconnect".localized))")
Logger.services.info(" [BLE] Disconnected: \(peripheral.name ?? "Unknown".localized, privacy: .public): \(String(describing: "User Initiated Disconnect".localized), privacy: .public)")
}
// Start a scan so the disconnected peripheral is moved to the peripherals[] if it is awake
self.startScanning()
@ -485,7 +485,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
}
let logString = String.localizedStringWithFormat("mesh.log.traceroute.sent %@".localized, destNum.toHex())
Logger.mesh.info("🪧 \(logString)")
Logger.mesh.info("🪧 \(logString, privacy: .public)")
} catch {
@ -498,14 +498,14 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
guard connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected else { return }
if FROMRADIO_characteristic == nil {
Logger.mesh.error("🚨 \("firmware.version.unsupported".localized)")
Logger.mesh.error("🚨 \("firmware.version.unsupported".localized, privacy: .public)")
invalidVersion = true
return
} else {
let nodeName = connectedPeripheral?.peripheral.name ?? "unknown".localized
let logString = String.localizedStringWithFormat("mesh.log.wantconfig %@".localized, nodeName)
Logger.mesh.info("🛎️ \(logString)")
Logger.mesh.info("🛎️ \(logString, privacy: .public)")
// BLE Characteristics discovered, issue wantConfig
var toRadio: ToRadio = ToRadio()
configNonce += 1
@ -750,7 +750,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
}
}
// Log any other unknownApp calls
if !nowKnown { Logger.mesh.info("🕸️ MESH PACKET received for Unknown App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure")") }
if !nowKnown { Logger.mesh.info("🕸️ MESH PACKET received for Unknown App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure", privacy: .public)") }
case .textMessageApp, .detectionSensorApp:
textMessageAppPacket(
packet: decodedInfo.packet,
@ -769,7 +769,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
appState: appState
)
case .remoteHardwareApp:
Logger.mesh.info("🕸️ MESH PACKET received for Remote Hardware App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure")")
Logger.mesh.info("🕸️ MESH PACKET received for Remote Hardware App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure", privacy: .public)")
case .positionApp:
upsertPositionPacket(packet: decodedInfo.packet, context: context)
case .waypointApp:
@ -971,33 +971,33 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
Logger.data.error("Error Updating Core Data TraceRouteHop: \(nsError, privacy: .public)")
}
let logString = String.localizedStringWithFormat("mesh.log.traceroute.received.route %@".localized, routeString)
Logger.mesh.info("🪧 \(logString)")
Logger.mesh.info("🪧 \(logString, privacy: .public)")
}
case .neighborinfoApp:
if let neighborInfo = try? NeighborInfo(serializedBytes: decodedInfo.packet.decoded.payload) {
Logger.mesh.info("🕸️ MESH PACKET received for Neighbor Info App UNHANDLED \((try? neighborInfo.jsonString()) ?? "JSON Decode Failure")")
Logger.mesh.info("🕸️ MESH PACKET received for Neighbor Info App UNHANDLED \((try? neighborInfo.jsonString()) ?? "JSON Decode Failure", privacy: .public)")
}
case .paxcounterApp:
paxCounterPacket(packet: decodedInfo.packet, context: context)
case .mapReportApp:
Logger.mesh.info("🕸️ MESH PACKET received Map Report App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure")")
Logger.mesh.info("🕸️ MESH PACKET received Map Report App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure", privacy: .public)")
case .UNRECOGNIZED:
Logger.mesh.info("🕸️ MESH PACKET received UNRECOGNIZED App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure")")
Logger.mesh.info("🕸️ MESH PACKET received UNRECOGNIZED App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure", privacy: .public)")
case .max:
Logger.services.info("MAX PORT NUM OF 511")
case .atakPlugin:
Logger.mesh.info("🕸️ MESH PACKET received for ATAK Plugin App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure")")
Logger.mesh.info("🕸️ MESH PACKET received for ATAK Plugin App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure", privacy: .public)")
case .powerstressApp:
Logger.mesh.info("🕸️ MESH PACKET received for Power Stress App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure")")
Logger.mesh.info("🕸️ MESH PACKET received for Power Stress App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure", privacy: .public)")
case .reticulumTunnelApp:
Logger.mesh.info("🕸️ MESH PACKET received for Reticulum Tunnel App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure")")
Logger.mesh.info("🕸️ MESH PACKET received for Reticulum Tunnel App UNHANDLED \((try? decodedInfo.packet.jsonString()) ?? "JSON Decode Failure", privacy: .public)")
}
if decodedInfo.configCompleteID != 0 && decodedInfo.configCompleteID == configNonce {
invalidVersion = false
lastConnectionError = ""
isSubscribed = true
Logger.mesh.info("🤜 [BLE] Want Config Complete. ID:\(decodedInfo.configCompleteID)")
Logger.mesh.info("🤜 [BLE] Want Config Complete. ID:\(decodedInfo.configCompleteID, privacy: .public)")
if sendTime() {
}
peripherals.removeAll(where: { $0.peripheral.state == CBPeripheralState.disconnected })
@ -1031,7 +1031,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
}
} catch {
Logger.data.error("Failed to find a node info for the connected node \(error.localizedDescription)")
Logger.data.error("Failed to find a node info for the connected node \(error.localizedDescription, privacy: .public)")
}
}
@ -1075,7 +1075,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
}
let nodeName = connectedPeripheral?.peripheral.name ?? "unknown".localized
let logString = String.localizedStringWithFormat("mesh.log.textmessage.send.failed %@".localized, nodeName)
Logger.mesh.info("🚫 \(logString)")
Logger.mesh.info("🚫 \(logString, privacy: .public)")
success = false
} else if message.count < 1 {
@ -1162,7 +1162,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
let logString = String.localizedStringWithFormat("mesh.log.textmessage.sent %@ %@ %@".localized, String(newMessage.messageId), fromUserNum.toHex(), toUserNum.toHex())
Logger.mesh.info("💬 \(logString)")
Logger.mesh.info("💬 \(logString, privacy: .public)")
do {
try context.save()
Logger.data.info("💾 Saved a new sent message from \(self.connectedPeripheral.num.toHex(), privacy: .public) to \(toUserNum.toHex(), privacy: .public)")
@ -1209,7 +1209,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
return false
}
let logString = String.localizedStringWithFormat("mesh.log.waypoint.sent %@".localized, String(fromNodeNum))
Logger.mesh.info("📍 \(logString)")
Logger.mesh.info("📍 \(logString, privacy: .public)")
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected {
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
success = true
@ -1373,7 +1373,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected {
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
let logString = String.localizedStringWithFormat("mesh.log.sharelocation %@".localized, String(fromNodeNum))
Logger.services.debug("📍 \(logString)")
Logger.services.debug("📍 \(logString, privacy: .public)")
return true
} else {
Logger.services.error("Device no longer connected. Unable to send position information.")
@ -1689,7 +1689,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
}
}
} catch {
Logger.data.error("Failed to find a node MyInfo to save these channels to: \(error.localizedDescription)")
Logger.data.error("Failed to find a node MyInfo to save these channels to: \(error.localizedDescription, privacy: .public)")
}
}
@ -1728,7 +1728,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected {
self.connectedPeripheral.peripheral.writeValue(binaryData, for: self.TORADIO_characteristic, type: .withResponse)
let logString = String.localizedStringWithFormat("mesh.log.channel.sent %@ %d".localized, String(connectedPeripheral.num), chan.index)
Logger.mesh.info("🎛️ \(logString)")
Logger.mesh.info("🎛️ \(logString, privacy: .public)")
}
}
// Save the LoRa Config and the device will reboot
@ -1757,7 +1757,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected {
self.connectedPeripheral.peripheral.writeValue(binaryData, for: self.TORADIO_characteristic, type: .withResponse)
let logString = String.localizedStringWithFormat("mesh.log.lora.config.sent %@".localized, String(connectedPeripheral.num))
Logger.mesh.info("📻 \(logString)")
Logger.mesh.info("📻 \(logString, privacy: .public)")
}
if self.connectedPeripheral != nil {
@ -1834,7 +1834,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
} catch {
context.rollback()
let nsError = error as NSError
Logger.data.error("🚫 Error deleting node from core data: \(nsError)")
Logger.data.error("🚫 Error deleting node from core data: \(nsError, privacy: .public)")
}
}
return false
@ -2677,7 +2677,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected {
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
let logString = String.localizedStringWithFormat("mesh.log.cannedmessages.messages.get %@".localized, String(connectedPeripheral.num))
Logger.mesh.info("🥫 \(logString)")
Logger.mesh.info("🥫 \(logString, privacy: .public)")
return true
}
@ -3257,7 +3257,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
if connectedPeripheral?.peripheral.state ?? CBPeripheralState.disconnected == CBPeripheralState.connected {
connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse)
Logger.mesh.debug("\(adminDescription)")
Logger.mesh.debug("\(adminDescription, privacy: .public)")
return true
}
return false
@ -3454,7 +3454,7 @@ extension BLEManager: CBCentralManagerDelegate {
default:
status = "default"
}
Logger.services.info("📜 [BLE] Bluetooth status: \(status)")
Logger.services.info("📜 [BLE] Bluetooth status: \(status, privacy: .public)")
}
// Called each time a peripheral is discovered

View file

@ -75,7 +75,7 @@ class LocalNotificationManager {
UNUserNotificationCenter.current().add(request) { error in
if let error {
Logger.services.error("Error Scheduling Notification: \(error.localizedDescription)")
Logger.services.error("Error Scheduling Notification: \(error.localizedDescription, privacy: .public)")
}
}
}

View file

@ -69,7 +69,7 @@ import OSLog
}
}
} catch {
Logger.services.error("💥 [App] Could not start location updates: \(error.localizedDescription)")
Logger.services.error("💥 [App] Could not start location updates: \(error.localizedDescription, privacy: .public)")
}
return
}

View file

@ -104,7 +104,7 @@ func moduleConfig (config: ModuleConfig, context: NSManagedObjectContext, nodeNu
func myInfoPacket (myInfo: MyNodeInfo, peripheralId: String, context: NSManagedObjectContext) -> MyInfoEntity? {
let logString = String.localizedStringWithFormat("mesh.log.myinfo %@".localized, String(myInfo.myNodeNum))
Logger.mesh.info(" \(logString)")
Logger.mesh.info(" \(logString, privacy: .public)")
let fetchMyInfoRequest = MyInfoEntity.fetchRequest()
fetchMyInfoRequest.predicate = NSPredicate(format: "myNodeNum == %lld", Int64(myInfo.myNodeNum))
@ -155,7 +155,7 @@ func channelPacket (channel: Channel, fromNum: Int64, context: NSManagedObjectCo
if channel.isInitialized && channel.hasSettings && channel.role != Channel.Role.disabled {
let logString = String.localizedStringWithFormat("mesh.log.channel.received %d %@".localized, channel.index, String(fromNum))
Logger.mesh.info("🎛️ \(logString)")
Logger.mesh.info("🎛️ \(logString, privacy: .public)")
let fetchedMyInfoRequest = MyInfoEntity.fetchRequest()
fetchedMyInfoRequest.predicate = NSPredicate(format: "myNodeNum == %lld", fromNum)
@ -194,7 +194,7 @@ func channelPacket (channel: Channel, fromNum: Int64, context: NSManagedObjectCo
} catch {
Logger.data.error("💥 Failed to save channel: \(error.localizedDescription, privacy: .public)")
}
Logger.data.info("💾 Updated MyInfo channel \(channel.index) from Channel App Packet For: \(fetchedMyInfo[0].myNodeNum)")
Logger.data.info("💾 Updated MyInfo channel \(channel.index, privacy: .public) from Channel App Packet For: \(fetchedMyInfo[0].myNodeNum, privacy: .public)")
} else if channel.role.rawValue > 0 {
Logger.data.error("💥Trying to save a channel to a MyInfo that does not exist: \(fromNum.toHex(), privacy: .public)")
}
@ -210,7 +210,7 @@ func deviceMetadataPacket (metadata: DeviceMetadata, fromNum: Int64, sessionPass
if metadata.isInitialized {
let logString = String.localizedStringWithFormat("mesh.log.device.metadata.received %@".localized, fromNum.toHex())
Logger.mesh.info("🏷️ \(logString)")
Logger.mesh.info("🏷️ \(logString, privacy: .public)")
let fetchedNodeRequest = NodeInfoEntity.fetchRequest()
fetchedNodeRequest.predicate = NSPredicate(format: "num == %lld", fromNum)
@ -262,7 +262,7 @@ func deviceMetadataPacket (metadata: DeviceMetadata, fromNum: Int64, sessionPass
func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObjectContext) -> NodeInfoEntity? {
let logString = String.localizedStringWithFormat("mesh.log.nodeinfo.received %@".localized, String(nodeInfo.num))
Logger.mesh.info("📟 \(logString)")
Logger.mesh.info("📟 \(logString, privacy: .public)")
guard nodeInfo.num > 0 else { return nil }
@ -350,12 +350,12 @@ func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObje
}
do {
try context.save()
Logger.data.info("💾 Saved a new Node Info For: \(String(nodeInfo.num))")
Logger.data.info("💾 Saved a new Node Info For: \(String(nodeInfo.num), privacy: .public)")
return newNode
} catch {
context.rollback()
let nsError = error as NSError
Logger.data.error("Error Saving Core Data NodeInfoEntity: \(nsError)")
Logger.data.error("Error Saving Core Data NodeInfoEntity: \(nsError, privacy: .public)")
}
} catch {
Logger.data.error("Fetch MyInfo Error")
@ -473,7 +473,7 @@ func adminAppPacket (packet: MeshPacket, context: NSManagedObjectContext) {
if !cmmc.messages.isEmpty {
let logString = String.localizedStringWithFormat("mesh.log.cannedmessages.messages.received %@".localized, packet.from.toHex())
Logger.mesh.info("🥫 \(logString)")
Logger.mesh.info("🥫 \(logString, privacy: .public)")
let fetchNodeRequest = NodeInfoEntity.fetchRequest()
fetchNodeRequest.predicate = NSPredicate(format: "num == %lld", Int64(packet.from))
@ -548,7 +548,7 @@ func adminAppPacket (packet: MeshPacket, context: NSManagedObjectContext) {
let ringtone = adminMessage.getRingtoneResponse
upsertRtttlConfigPacket(ringtone: ringtone, nodeNum: Int64(packet.from), context: context)
} else {
Logger.mesh.error("🕸️ MESH PACKET received Admin App UNHANDLED \((try? packet.decoded.jsonString()) ?? "JSON Decode Failure")")
Logger.mesh.error("🕸️ MESH PACKET received Admin App UNHANDLED \((try? packet.decoded.jsonString()) ?? "JSON Decode Failure", privacy: .public)")
}
// Save an ack for the admin message log for each admin message response received as we stopped sending acks if there is also a response to reduce airtime.
adminResponseAck(packet: packet, context: context)
@ -573,17 +573,17 @@ func adminResponseAck (packet: MeshPacket, context: NSManagedObjectContext) {
do {
try context.save()
} catch {
Logger.data.error("Failed to save admin message response as an ack: \(error.localizedDescription)")
Logger.data.error("Failed to save admin message response as an ack: \(error.localizedDescription, privacy: .public)")
}
}
} catch {
Logger.data.error("Failed to fetch admin message by requestID: \(error.localizedDescription)")
Logger.data.error("Failed to fetch admin message by requestID: \(error.localizedDescription, privacy: .public)")
}
}
func paxCounterPacket (packet: MeshPacket, context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.paxcounter %@".localized, String(packet.from))
Logger.mesh.info("🧑‍🤝‍🧑 \(logString)")
Logger.mesh.info("🧑‍🤝‍🧑 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(packet.from))
@ -608,7 +608,7 @@ func paxCounterPacket (packet: MeshPacket, context: NSManagedObjectContext) {
do {
try context.save()
} catch {
Logger.data.error("Failed to save pax: \(error.localizedDescription)")
Logger.data.error("Failed to save pax: \(error.localizedDescription, privacy: .public)")
}
} else {
Logger.data.info("Node Info Not Found")
@ -627,7 +627,7 @@ func routingPacket (packet: MeshPacket, connectedNodeNum: Int64, context: NSMana
let routingErrorString = routingError?.display ?? "unknown".localized
let logString = String.localizedStringWithFormat("mesh.log.routing.message %@ %@".localized, String(packet.decoded.requestID), routingErrorString)
Logger.mesh.info("🕸️ \(logString)")
Logger.mesh.info("🕸️ \(logString, privacy: .public)")
let fetchMessageRequest = MessageEntity.fetchRequest()
fetchMessageRequest.predicate = NSPredicate(format: "messageId == %lld", Int64(packet.decoded.requestID))
@ -674,11 +674,11 @@ func routingPacket (packet: MeshPacket, connectedNodeNum: Int64, context: NSMana
return
}
try context.save()
Logger.data.info("💾 ACK Saved for Message: \(packet.decoded.requestID)")
Logger.data.info("💾 ACK Saved for Message: \(packet.decoded.requestID, privacy: .public)")
} catch {
context.rollback()
let nsError = error as NSError
Logger.data.error("Error Saving ACK for message: \(packet.id) Error: \(nsError)")
Logger.data.error("Error Saving ACK for message: \(packet.id, privacy: .public) Error: \(nsError, privacy: .public)")
}
}
}
@ -688,7 +688,7 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage
if let telemetryMessage = try? Telemetry(serializedBytes: packet.decoded.payload) {
let logString = String.localizedStringWithFormat("mesh.log.telemetry.received %@".localized, String(packet.from))
Logger.mesh.info("📈 \(logString)")
Logger.mesh.info("📈 \(logString, privacy: .public)")
if telemetryMessage.variant != Telemetry.OneOf_Variant.deviceMetrics(telemetryMessage.deviceMetrics) && telemetryMessage.variant != Telemetry.OneOf_Variant.environmentMetrics(telemetryMessage.environmentMetrics) && telemetryMessage.variant != Telemetry.OneOf_Variant.localStats(telemetryMessage.localStats) && telemetryMessage.variant != Telemetry.OneOf_Variant.powerMetrics(telemetryMessage.powerMetrics) {
/// Other unhandled telemetry packets
@ -782,7 +782,7 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage
}
try context.save()
Logger.data.info("💾 [TelemetryEntity] of type \(MetricsTypes(rawValue: Int(telemetry.metricsType))?.name ?? "Unknown Metrics Type") Saved for Node: \(packet.from.toHex())")
Logger.data.info("💾 [TelemetryEntity] of type \(MetricsTypes(rawValue: Int(telemetry.metricsType))?.name ?? "Unknown Metrics Type", privacy: .public) Saved for Node: \(packet.from.toHex(), privacy: .public)")
if telemetry.metricsType == 0 {
// Connected Device Metrics
// ------------------------
@ -883,7 +883,7 @@ func textMessageAppPacket(
}
if messageText?.count ?? 0 > 0 {
Logger.mesh.info("💬 \("mesh.log.textmessage.received".localized)")
Logger.mesh.info("💬 \("mesh.log.textmessage.received".localized, privacy: .public)")
let messageUsers = UserEntity.fetchRequest()
messageUsers.predicate = NSPredicate(format: "num IN %@", [packet.to, packet.from])
do {
@ -959,7 +959,7 @@ func textMessageAppPacket(
var messageSaved = false
do {
try context.save()
Logger.data.info("💾 Saved a new message for \(newMessage.messageId)")
Logger.data.info("💾 Saved a new message for \(newMessage.messageId, privacy: .public)")
messageSaved = true
if messageSaved {
@ -989,7 +989,7 @@ func textMessageAppPacket(
)
]
manager.schedule()
Logger.services.debug("iOS Notification Scheduled for text message from \(newMessage.fromUser?.longName ?? "unknown".localized)")
Logger.services.debug("iOS Notification Scheduled for text message from \(newMessage.fromUser?.longName ?? "unknown".localized, privacy: .public)")
}
} else if newMessage.fromUser != nil && newMessage.toUser == nil {
let fetchMyInfoRequest = MyInfoEntity.fetchRequest()
@ -1021,7 +1021,7 @@ func textMessageAppPacket(
critical: critical)
]
manager.schedule()
Logger.services.debug("iOS Notification Scheduled for text message from \(newMessage.fromUser?.longName ?? "unknown".localized)")
Logger.services.debug("iOS Notification Scheduled for text message from \(newMessage.fromUser?.longName ?? "unknown".localized, privacy: .public)")
}
}
}
@ -1033,7 +1033,7 @@ func textMessageAppPacket(
} catch {
context.rollback()
let nsError = error as NSError
Logger.data.error("Failed to save new MessageEntity \(nsError)")
Logger.data.error("Failed to save new MessageEntity \(nsError, privacy: .public)")
}
} catch {
Logger.data.error("Fetch Message To and From Users Error")
@ -1044,7 +1044,7 @@ func textMessageAppPacket(
func waypointPacket (packet: MeshPacket, context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.waypoint.received %@".localized, String(packet.from))
Logger.mesh.info("📍 \(logString)")
Logger.mesh.info("📍 \(logString, privacy: .public)")
let fetchWaypointRequest = WaypointEntity.fetchRequest()
fetchWaypointRequest.predicate = NSPredicate(format: "id == %lld", Int64(packet.id))
@ -1071,7 +1071,7 @@ func waypointPacket (packet: MeshPacket, context: NSManagedObjectContext) {
waypoint.created = Date()
do {
try context.save()
Logger.data.info("💾 Added Node Waypoint App Packet For: \(waypoint.id)")
Logger.data.info("💾 Added Node Waypoint App Packet For: \(waypoint.id, privacy: .public)")
let manager = LocalNotificationManager()
let icon = String(UnicodeScalar(Int(waypoint.icon)) ?? "📍")
let latitude = Double(waypoint.latitudeI) / 1e7
@ -1086,12 +1086,12 @@ func waypointPacket (packet: MeshPacket, context: NSManagedObjectContext) {
path: "meshtastic:///map?waypointid=\(waypoint.id)"
)
]
Logger.data.debug("meshtastic:///map?waypointid=\(waypoint.id)")
Logger.data.debug("meshtastic:///map?waypointid=\(waypoint.id, privacy: .public)")
manager.schedule()
} catch {
context.rollback()
let nsError = error as NSError
Logger.data.error("Error Saving WaypointEntity from WAYPOINT_APP \(nsError)")
Logger.data.error("Error Saving WaypointEntity from WAYPOINT_APP \(nsError, privacy: .public)")
}
} else {
fetchedWaypoint[0].id = Int64(packet.id)
@ -1109,11 +1109,11 @@ func waypointPacket (packet: MeshPacket, context: NSManagedObjectContext) {
fetchedWaypoint[0].lastUpdated = Date()
do {
try context.save()
Logger.data.info("💾 Updated Node Waypoint App Packet For: \(fetchedWaypoint[0].id)")
Logger.data.info("💾 Updated Node Waypoint App Packet For: \(fetchedWaypoint[0].id, privacy: .public)")
} catch {
context.rollback()
let nsError = error as NSError
Logger.data.error("Error Saving WaypointEntity from WAYPOINT_APP \(nsError)")
Logger.data.error("Error Saving WaypointEntity from WAYPOINT_APP \(nsError, privacy: .public)")
}
}
}

View file

@ -55,7 +55,7 @@ struct MeshtasticAppleApp: App {
.presentationDragIndicator(.visible)
}
.onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { userActivity in
Logger.mesh.debug("URL received \(userActivity)")
Logger.mesh.debug("URL received \(userActivity, privacy: .public)")
self.incomingUrl = userActivity.webpageURL
if (self.incomingUrl?.absoluteString.lowercased().contains("meshtastic.org/e/#")) != nil {
@ -72,18 +72,18 @@ struct MeshtasticAppleApp: App {
}
self.channelSettings = cs
}
Logger.services.debug("Add Channel \(self.addChannels)")
Logger.services.debug("Add Channel \(self.addChannels, privacy: .public)")
}
self.saveChannels = true
Logger.mesh.debug("User wants to open a Channel Settings URL: \(self.incomingUrl?.absoluteString ?? "No QR Code Link")")
}
if self.saveChannels {
Logger.mesh.debug("User wants to open Channel Settings URL: \(String(describing: self.incomingUrl!.relativeString))")
Logger.mesh.debug("User wants to open Channel Settings URL: \(String(describing: self.incomingUrl!.relativeString), privacy: .public)")
}
}
.onOpenURL(perform: { (url) in
Logger.mesh.debug("Some sort of URL was received \(url)")
Logger.mesh.debug("Some sort of URL was received \(url, privacy: .public)")
self.incomingUrl = url
if url.absoluteString.lowercased().contains("meshtastic.org/e/#") {
if let components = self.incomingUrl?.absoluteString.components(separatedBy: "#") {
@ -99,10 +99,10 @@ struct MeshtasticAppleApp: App {
}
self.channelSettings = cs
}
Logger.services.debug("Add Channel \(self.addChannels)")
Logger.services.debug("Add Channel \(self.addChannels, privacy: .public)")
}
self.saveChannels = true
Logger.mesh.debug("User wants to open a Channel Settings URL: \(self.incomingUrl?.absoluteString ?? "No QR Code Link")")
Logger.mesh.debug("User wants to open a Channel Settings URL: \(self.incomingUrl?.absoluteString ?? "No QR Code Link", privacy: .public)")
} else if url.absoluteString.lowercased().contains("meshtastic:///") {
appState.router.route(url: url)
}

View file

@ -97,10 +97,10 @@ class MeshtasticAppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificat
if let targetValue = userInfo["target"] as? String,
let deepLink = userInfo["path"] as? String,
let url = URL(string: deepLink) {
Logger.services.info("userNotificationCenter didReceiveResponse \(targetValue) \(deepLink)")
Logger.services.info("userNotificationCenter didReceiveResponse \(targetValue, privacy: .public) \(deepLink, privacy: .public)")
router?.route(url: url)
} else {
Logger.services.error("Failed to handle notification response: \(userInfo)")
Logger.services.error("Failed to handle notification response: \(userInfo, privacy: .public)")
}
completionHandler()
}

View file

@ -94,7 +94,6 @@ class MetricsSeriesList: ObservableObject, RandomAccessCollection, RangeReplacea
if let minimumSpan = aSeries.minumumYAxisSpan,
let currentRange = range[aSeries] {
let currentSpan = currentRange.upperBound - currentRange.lowerBound
//Logger.data.info("Updated \(aSeries.id) to \(range[aSeries] ?? 0...0) span=\(currentSpan)")
if currentSpan < minimumSpan {
// Calculate the center of the range
let centerOfRange = currentRange.lowerBound + (currentSpan / 2)
@ -118,7 +117,6 @@ class MetricsSeriesList: ObservableObject, RandomAccessCollection, RangeReplacea
return globalLower...globalUpper
}
// Collection conformance
typealias Index = Int
typealias Element = MetricsChartSeries

View file

@ -48,7 +48,7 @@ class PersistenceController {
if let error = error as NSError? {
Logger.data.error("CoreData Error: \(error.localizedDescription). Now attempting to truncate CoreData database. All app data will be lost.")
Logger.data.error("CoreData Error: \(error.localizedDescription, privacy: .public). Now attempting to truncate CoreData database. All app data will be lost.")
self.clearDatabase()
}
})
@ -65,11 +65,11 @@ class PersistenceController {
do {
try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: nil)
} catch let error {
Logger.data.error("Failed to re-create CoreData database: \(error.localizedDescription)")
Logger.data.error("Failed to re-create CoreData database: \(error.localizedDescription, privacy: .public)")
}
} catch let error {
Logger.data.error("Failed to destroy CoreData database, delete the app and re-install to clear data. Attempted to clear persistent store: \(error.localizedDescription)")
Logger.data.error("Failed to destroy CoreData database, delete the app and re-install to clear data. Attempted to clear persistent store: \(error.localizedDescription, privacy: .public)")
}
}
}

View file

@ -85,7 +85,7 @@ public func deleteChannelMessages(channel: ChannelEntity, context: NSManagedObje
}
try context.save()
} catch let error as NSError {
Logger.data.error("\(error.localizedDescription)")
Logger.data.error("\(error.localizedDescription, privacy: .public)")
}
}
@ -98,7 +98,7 @@ public func deleteUserMessages(user: UserEntity, context: NSManagedObjectContext
}
try context.save()
} catch let error as NSError {
Logger.data.error("\(error.localizedDescription)")
Logger.data.error("\(error.localizedDescription, privacy: .public)")
}
}
@ -122,7 +122,7 @@ public func clearCoreDataDatabase(context: NSManagedObjectContext, includeRoutes
do {
try context.executeAndMergeChanges(using: deleteRequest)
} catch {
Logger.data.error("\(error.localizedDescription)")
Logger.data.error("\(error.localizedDescription, privacy: .public)")
}
}
}
@ -130,7 +130,7 @@ public func clearCoreDataDatabase(context: NSManagedObjectContext, includeRoutes
func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.nodeinfo.received %@".localized, packet.from.toHex())
Logger.mesh.info("📟 \(logString)")
Logger.mesh.info("📟 \(logString, privacy: .public)")
guard packet.from > 0 else { return }
@ -313,7 +313,7 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext)
func upsertPositionPacket (packet: MeshPacket, context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.position.received %@".localized, String(packet.from))
Logger.mesh.info("📍 \(logString)")
Logger.mesh.info("📍 \(logString, privacy: .public)")
let fetchNodePositionRequest = NodeInfoEntity.fetchRequest()
fetchNodePositionRequest.predicate = NSPredicate(format: "num == %lld", Int64(packet.from))
@ -407,7 +407,7 @@ func upsertPositionPacket (packet: MeshPacket, context: NSManagedObjectContext)
func upsertBluetoothConfigPacket(config: Config.BluetoothConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.bluetooth.config %@".localized, String(nodeNum))
Logger.mesh.info("📶 \(logString)")
Logger.mesh.info("📶 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
@ -451,7 +451,7 @@ func upsertBluetoothConfigPacket(config: Config.BluetoothConfig, nodeNum: Int64,
func upsertDeviceConfigPacket(config: Config.DeviceConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.device.config %@".localized, String(nodeNum))
Logger.mesh.info("📟 \(logString)")
Logger.mesh.info("📟 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
@ -506,7 +506,7 @@ func upsertDeviceConfigPacket(config: Config.DeviceConfig, nodeNum: Int64, sessi
func upsertDisplayConfigPacket(config: Config.DisplayConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.display.config %@".localized, nodeNum.toHex())
Logger.data.info("🖥️ \(logString)")
Logger.data.info("🖥️ \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
@ -551,19 +551,15 @@ func upsertDisplayConfigPacket(config: Config.DisplayConfig, nodeNum: Int64, ses
Logger.data.info("💾 [DisplayConfigEntity] Updated for node: \(nodeNum.toHex(), privacy: .public)")
} catch {
context.rollback()
let nsError = error as NSError
Logger.data.error("💥 [DisplayConfigEntity] Error Updating Core Data: \(nsError, privacy: .public)")
}
} else {
Logger.data.error("💥 [DisplayConfigEntity] No Nodes found in local database matching node \(nodeNum.toHex()) unable to save Display Config")
Logger.data.error("💥 [DisplayConfigEntity] No Nodes found in local database matching node \(nodeNum.toHex(), privacy: .public) unable to save Display Config")
}
} catch {
let nsError = error as NSError
Logger.data.error("💥 [DisplayConfigEntity] Fetching node for core data failed: \(nsError, privacy: .public)")
}
@ -572,7 +568,7 @@ func upsertDisplayConfigPacket(config: Config.DisplayConfig, nodeNum: Int64, ses
func upsertLoRaConfigPacket(config: Config.LoRaConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.lora.config %@".localized, nodeNum.toHex())
Logger.data.info("📻 \(logString)")
Logger.data.info("📻 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", nodeNum)
@ -643,7 +639,7 @@ func upsertLoRaConfigPacket(config: Config.LoRaConfig, nodeNum: Int64, sessionPa
func upsertNetworkConfigPacket(config: Config.NetworkConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.network.config %@".localized, String(nodeNum))
Logger.data.info("🌐 \(logString)")
Logger.data.info("🌐 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
@ -692,7 +688,7 @@ func upsertNetworkConfigPacket(config: Config.NetworkConfig, nodeNum: Int64, ses
func upsertPositionConfigPacket(config: Config.PositionConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.position.config %@".localized, String(nodeNum))
Logger.data.info("🗺️ \(logString)")
Logger.data.info("🗺️ \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
@ -755,7 +751,7 @@ func upsertPositionConfigPacket(config: Config.PositionConfig, nodeNum: Int64, s
func upsertPowerConfigPacket(config: Config.PowerConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.power.config %@".localized, String(nodeNum))
Logger.data.info("🗺️ \(logString)")
Logger.data.info("🗺️ \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
@ -807,7 +803,7 @@ func upsertPowerConfigPacket(config: Config.PowerConfig, nodeNum: Int64, session
func upsertSecurityConfigPacket(config: Config.SecurityConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.security.config %@".localized, String(nodeNum))
Logger.data.info("🛡️ \(logString)")
Logger.data.info("🛡️ \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
@ -868,7 +864,7 @@ func upsertSecurityConfigPacket(config: Config.SecurityConfig, nodeNum: Int64, s
func upsertAmbientLightingModuleConfigPacket(config: ModuleConfig.AmbientLightingConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.ambientlighting.config %@".localized, String(nodeNum))
Logger.data.info("🏮 \(logString)")
Logger.data.info("🏮 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
@ -921,7 +917,7 @@ func upsertAmbientLightingModuleConfigPacket(config: ModuleConfig.AmbientLightin
func upsertCannedMessagesModuleConfigPacket(config: ModuleConfig.CannedMessageConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.cannedmessage.config %@".localized, String(nodeNum))
Logger.data.info("🥫 \(logString)")
Logger.data.info("🥫 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
@ -980,7 +976,7 @@ func upsertCannedMessagesModuleConfigPacket(config: ModuleConfig.CannedMessageCo
func upsertDetectionSensorModuleConfigPacket(config: ModuleConfig.DetectionSensorConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.detectionsensor.config %@".localized, String(nodeNum))
Logger.data.info("🕵️ \(logString)")
Logger.data.info("🕵️ \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
@ -1037,7 +1033,7 @@ func upsertDetectionSensorModuleConfigPacket(config: ModuleConfig.DetectionSenso
func upsertExternalNotificationModuleConfigPacket(config: ModuleConfig.ExternalNotificationConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.externalnotification.config %@".localized, String(nodeNum))
Logger.data.info("📣 \(logString)")
Logger.data.info("📣 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
@ -1106,7 +1102,7 @@ func upsertExternalNotificationModuleConfigPacket(config: ModuleConfig.ExternalN
func upsertPaxCounterModuleConfigPacket(config: ModuleConfig.PaxcounterConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.paxcounter.config %@".localized, String(nodeNum))
Logger.data.info("🧑‍🤝‍🧑 \(logString)")
Logger.data.info("🧑‍🤝‍🧑 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
@ -1148,7 +1144,7 @@ func upsertPaxCounterModuleConfigPacket(config: ModuleConfig.PaxcounterConfig, n
func upsertRtttlConfigPacket(ringtone: String, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.ringtone.config %@".localized, String(nodeNum))
Logger.data.info("⛰️ \(logString)")
Logger.data.info("⛰️ \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
@ -1188,7 +1184,7 @@ func upsertRtttlConfigPacket(ringtone: String, nodeNum: Int64, sessionPasskey: D
func upsertMqttModuleConfigPacket(config: ModuleConfig.MQTTConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.mqtt.config %@".localized, String(nodeNum))
Logger.data.info("🌉 \(logString)")
Logger.data.info("🌉 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
@ -1250,7 +1246,7 @@ func upsertMqttModuleConfigPacket(config: ModuleConfig.MQTTConfig, nodeNum: Int6
func upsertRangeTestModuleConfigPacket(config: ModuleConfig.RangeTestConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.rangetest.config %@".localized, String(nodeNum))
Logger.data.info("⛰️ \(logString)")
Logger.data.info("⛰️ \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
@ -1294,7 +1290,7 @@ func upsertRangeTestModuleConfigPacket(config: ModuleConfig.RangeTestConfig, nod
func upsertSerialModuleConfigPacket(config: ModuleConfig.SerialConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.serial.config %@".localized, String(nodeNum))
Logger.data.info("🤖 \(logString)")
Logger.data.info("🤖 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
@ -1349,7 +1345,7 @@ func upsertSerialModuleConfigPacket(config: ModuleConfig.SerialConfig, nodeNum:
func upsertStoreForwardModuleConfigPacket(config: ModuleConfig.StoreForwardConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.storeforward.config %@".localized, String(nodeNum))
Logger.data.info("📬 \(logString)")
Logger.data.info("📬 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
@ -1397,7 +1393,7 @@ func upsertStoreForwardModuleConfigPacket(config: ModuleConfig.StoreForwardConfi
func upsertTelemetryModuleConfigPacket(config: ModuleConfig.TelemetryConfig, nodeNum: Int64, sessionPasskey: Data? = Data(), context: NSManagedObjectContext) {
let logString = String.localizedStringWithFormat("mesh.log.telemetry.config %@".localized, String(nodeNum))
Logger.data.info("📈 \(logString)")
Logger.data.info("📈 \(logString, privacy: .public)")
let fetchNodeInfoRequest = NodeInfoEntity.fetchRequest()
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))

View file

@ -44,7 +44,7 @@ class Router: ObservableObject {
} else if components.path.hasPrefix("/settings") {
routeSettings(components)
} else {
Logger.services.warning("Failed to route url: \(url)")
Logger.services.warning("Failed to route url: \(url, privacy: .public)")
}
}

View file

@ -35,7 +35,7 @@ struct Connect: View {
if success {
Logger.services.info("Notifications are all set!")
} else if let error = error {
Logger.services.error("\(error.localizedDescription)")
Logger.services.error("\(error.localizedDescription, privacy: .public)")
}
}
}
@ -324,7 +324,7 @@ struct Connect: View {
isUnsetRegion = false
}
} catch {
Logger.data.error("💥 Error fetching node info: \(error.localizedDescription)")
Logger.data.error("💥 Error fetching node info: \(error.localizedDescription, privacy: .public)")
}
}
}
@ -361,7 +361,7 @@ struct Connect: View {
pushType: nil)
Logger.services.info("Requested MyActivity live activity. ID: \(myActivity.id)")
} catch {
Logger.services.error("Error requesting live activity: \(error.localizedDescription)")
Logger.services.error("Error requesting live activity: \(error.localizedDescription, privacy: .public)")
}
}

View file

@ -64,7 +64,7 @@ struct LocalWeatherConditions: View {
attributionLogo = colorScheme == .light ? attribution.combinedMarkLightURL : attribution.combinedMarkDarkURL
}
} catch {
Logger.services.error("Could not gather weather information: \(error.localizedDescription)")
Logger.services.error("Could not gather weather information: \(error.localizedDescription, privacy: .public)")
condition = .clear
symbolName = "cloud.fill"
}

View file

@ -35,7 +35,7 @@ struct NodeWeatherForecastView: View {
)
})
} catch {
Logger.services.error("Could not load weather: \(error.localizedDescription)")
Logger.services.error("Could not load weather: \(error.localizedDescription, privacy: .public)")
}
}
}

View file

@ -1,64 +0,0 @@
//
//// MapButtons.swift
//// Meshtastic
////
//// Copyright © Garth Vander Houwen 4/23/23.
////
//
//import SwiftUI
//
//struct MapButtons: View {
// let buttonWidth: CGFloat = 22
// let width: CGFloat = 45
// @Binding var tracking: UserTrackingModes
// @Binding var isPresentingInfoSheet: Bool
// var body: some View {
// VStack {
// let impactLight = UIImpactFeedbackGenerator(style: .light)
// Button(action: {
// self.isPresentingInfoSheet.toggle()
// }) {
// Image(systemName: isPresentingInfoSheet ? "info.circle.fill" : "info.circle")
// .resizable()
// .frame(width: buttonWidth, height: buttonWidth, alignment: .center)
// .offset(y: -2)
// }
// Divider()
// Button(action: {
// switch self.tracking {
// case .none:
// self.tracking = .follow
// case .follow:
// self.tracking = .followWithHeading
// case .followWithHeading:
// self.tracking = .none
// }
// impactLight.impactOccurred()
// }) {
// Image(systemName: tracking.icon)
// .frame(width: buttonWidth, height: buttonWidth, alignment: .center)
// .offset(y: 3)
// }
// }
// .frame(width: width, height: width*2, alignment: .center)
// .background(Color(UIColor.systemBackground))
// .cornerRadius(8)
// .shadow(radius: 1)
// .offset(x: 3, y: 25)
// }
//}
//
//// MARK: Previews
//// struct MapControl_Previews: PreviewProvider {
//// @State static var tracking: UserTrackingModes = .none
//// @State static var isPresentingInfoSheet = false
//// static var previews: some View {
//// Group {
//// MapButtons(tracking: $tracking, isPresentingInfoSheet: $isPresentingInfoSheet)
//// .environment(\.colorScheme, .light)
//// MapButtons(tracking: $tracking, isPresentingInfoSheet: $isPresentingInfoSheet)
//// .environment(\.colorScheme, .dark)
//// }
//// .previewLayout(.fixed(width: 60, height: 100))
//// }
//// }

View file

@ -1,37 +0,0 @@
//
// MapViewFitExtension.swift
// Meshtastic
//
// Created by Garth Vander Houwen on 1/15/23.
//
import MapKit
extension MKMapView {
func fitAllAnnotations(with padding: UIEdgeInsets = UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100)) {
var zoomRect: MKMapRect = .null
annotations.forEach({
let annotationPoint = MKMapPoint($0.coordinate)
let pointRect = MKMapRect(x: annotationPoint.x, y: annotationPoint.y, width: 0.01, height: 0.01)
zoomRect = zoomRect.union(pointRect)
})
setVisibleMapRect(zoomRect, edgePadding: padding, animated: true)
}
func fit(annotations: [MKAnnotation], andShow show: Bool, with padding: UIEdgeInsets = UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100)) {
var zoomRect: MKMapRect = .null
annotations.forEach({
let aPoint = MKMapPoint($0.coordinate)
let rect = MKMapRect(x: aPoint.x, y: aPoint.y, width: 0.1, height: 0.1)
zoomRect = zoomRect.isNull ? rect : zoomRect.union(rect)
})
if show {
addAnnotations(annotations)
}
setVisibleMapRect(zoomRect, edgePadding: padding, animated: true)
}
}

View file

@ -1,434 +0,0 @@
////
//// MapViewSwitUI.swift
//// Meshtastic
////
//// Copyright(c) Josh Pirihi & Garth Vander Houwen 1/16/22.
//
//import Foundation
//import SwiftUI
//import MapKit
//import OSLog
//
//struct PolygonInfo: Codable {
// let stroke: String?
// let strokeWidth, strokeOpacity: Int?
// let fill: String?
// let fillOpacity: Double?
// let title, subtitle: String?
//}
//
//func degreesToRadians(_ number: Double) -> Double {
// return number * .pi / 180
//}
//var currentMapLayer: MapLayer?
//
//struct MapViewSwiftUI: UIViewRepresentable {
// var onLongPress: (_ waypointCoordinate: CLLocationCoordinate2D) -> Void
// var onWaypointEdit: (_ waypointId: Int ) -> Void
// let mapView = MKMapView()
// // Parameters
// let selectedMapLayer: MapLayer
// let selectedWeatherLayer: MapOverlayServer = UserDefaults.mapOverlayServer
// let positions: [PositionEntity]
// let waypoints: [WaypointEntity]
// let userTrackingMode: MKUserTrackingMode
// let showNodeHistory: Bool
// let showRouteLines: Bool
// let mapViewType: MKMapType = MKMapType.standard
// // Offline Map Tiles
// @AppStorage("lastUpdatedLocalMapFile") private var lastUpdatedLocalMapFile = 0
// @State private var loadedLastUpdatedLocalMapFile = 0
// var customMapOverlay: CustomMapOverlay?
// @State private var presentCustomMapOverlayHash: CustomMapOverlay?
// // MARK: Private methods
// private func configureMap(mapView: MKMapView) {
// // Map View Parameters
// mapView.mapType = mapViewType
// mapView.addAnnotations(waypoints)
// // Do the initial map centering
// let latest = positions
// .filter { $0.latest == true }
// .sorted { $0.nodePosition?.num ?? 0 > $1.nodePosition?.num ?? -1 }
// let span = MKCoordinateSpan(latitudeDelta: 0.003, longitudeDelta: 0.003)
// let center = (latest.count > 0 && userTrackingMode == MKUserTrackingMode.none) ? latest[0].coordinate : LocationHelper.currentLocation
// let region = MKCoordinateRegion(center: center, span: span)
// mapView.addAnnotations(showNodeHistory ? positions : latest)
// mapView.setRegion(region, animated: true)
// // Set user (phone gps) tracking options
// mapView.setUserTrackingMode(userTrackingMode, animated: true)
// if userTrackingMode == MKUserTrackingMode.none {
// if latest.count == 1 {
// mapView.fit(annotations: showNodeHistory ? positions: latest, andShow: false)
// } else {
// mapView.fitAllAnnotations()
// }
// mapView.showsUserLocation = false
// } else {
// mapView.showsUserLocation = true
// }
// // Other MKMapView Settings
// mapView.preferredConfiguration.elevationStyle = .realistic// .flat
// mapView.pointOfInterestFilter = MKPointOfInterestFilter.excludingAll
// mapView.isPitchEnabled = true
// mapView.isRotateEnabled = true
// mapView.isScrollEnabled = true
// mapView.isZoomEnabled = true
// mapView.showsBuildings = true
// mapView.showsScale = true
// mapView.showsTraffic = true
//
// mapView.showsCompass = false
// let compass = MKCompassButton(mapView: mapView)
// compass.translatesAutoresizingMaskIntoConstraints = false
// #if targetEnvironment(macCatalyst)
// // Show the default always visible compass and the mac only controls
// compass.compassVisibility = .visible
// mapView.addSubview(compass)
// mapView.showsZoomControls = true
// mapView.showsPitchControl = true
// compass.trailingAnchor.constraint(equalTo: mapView.trailingAnchor, constant: -115).isActive = true
// compass.bottomAnchor.constraint(equalTo: mapView.bottomAnchor, constant: -5).isActive = true
// #else
// compass.compassVisibility = .adaptive
// mapView.addSubview(compass)
// compass.trailingAnchor.constraint(equalTo: mapView.trailingAnchor, constant: -5).isActive = true
// compass.topAnchor.constraint(equalTo: mapView.topAnchor, constant: 145).isActive = true
// #endif
// }
// private func setMapBaseLayer(mapView: MKMapView) {
// // Avoid refreshing UI if selectedLayer has not changed
// guard currentMapLayer != selectedMapLayer else { return }
// currentMapLayer = selectedMapLayer
// for overlay in mapView.overlays where overlay is MKTileOverlay {
// mapView.removeOverlay(overlay)
// }
// switch selectedMapLayer {
// case .offline:
// mapView.mapType = .standard
// let overlay = TileOverlay()
// overlay.canReplaceMapContent = false
// overlay.minimumZ = UserDefaults.mapTileServer.zoomRange.startIndex
// overlay.maximumZ = UserDefaults.mapTileServer.zoomRange.endIndex
// mapView.addOverlay(overlay, level: UserDefaults.mapTilesAboveLabels ? .aboveLabels : .aboveRoads)
// case .satellite:
// mapView.mapType = .satellite
// case .hybrid:
// mapView.mapType = .hybrid
// default:
// mapView.mapType = .standard
// }
// }
// private func setMapOverlays(mapView: MKMapView) {
// // Weather radar
// if UserDefaults.enableOverlayServer {
// let locale = Locale.current
// if locale.region?.identifier ?? "no locale" == "US" {
// let overlay = MKTileOverlay(urlTemplate: selectedWeatherLayer.tileUrl)
// overlay.canReplaceMapContent = false
// overlay.minimumZ = selectedWeatherLayer.zoomRange.startIndex
// overlay.maximumZ = selectedWeatherLayer.zoomRange.endIndex
// mapView.addOverlay(overlay, level: .aboveLabels)
// }
// }
// }
//
// func makeUIView(context: Context) -> MKMapView {
// currentMapLayer = nil
// mapView.delegate = context.coordinator
// self.configureMap(mapView: mapView)
// return mapView
// }
// func updateUIView(_ mapView: MKMapView, context: Context) {
// // Set selected map base layer
// setMapBaseLayer(mapView: mapView)
// // Set map tile server and weather overlay layers
// setMapOverlays(mapView: mapView)
// let latest = positions
// .filter { $0.latest == true }
// .sorted { $0.nodePosition?.num ?? 0 > $1.nodePosition?.num ?? -1 }
// // Node Route Lines
// if showRouteLines {
// // Remove all existing PolyLine Overlays
// for overlay in mapView.overlays where overlay is MKPolyline {
// mapView.removeOverlay(overlay)
// }
// var lineIndex = 0
// for position in latest {
// let nodePositions = positions.filter { $0.nodeCoordinate != nil && $0.nodePosition?.num ?? 0 == position.nodePosition?.num ?? -1 }
// let lineCoords = nodePositions.compactMap({(position) -> CLLocationCoordinate2D in
// return position.nodeCoordinate ?? LocationHelper.DefaultLocation
// })
// let polyline = MKPolyline(coordinates: lineCoords, count: nodePositions.count)
// polyline.title = "\(String(position.nodePosition?.num ?? 0))"
// mapView.addOverlay(polyline, level: .aboveLabels)
// lineIndex += 1
// // There are 18 colors for lines, start over if we are at index 17
// if lineIndex > 17 {
// lineIndex = 0
// }
// }
// } else {
// // Remove all existing PolyLine Overlays
// for overlay in mapView.overlays where overlay is MKPolyline {
// mapView.removeOverlay(overlay)
// }
// }
// let annotationCount = waypoints.count + (showNodeHistory ? positions.count : latest.count)
// if annotationCount != mapView.annotations.count {
// Logger.services.info("Annotation Count: \(annotationCount) Map Annotations: \(mapView.annotations.count)")
// mapView.removeAnnotations(mapView.annotations)
// mapView.addAnnotations(waypoints)
// }
// mapView.addAnnotations(showNodeHistory ? positions : latest)
// if userTrackingMode == MKUserTrackingMode.none {
// mapView.showsUserLocation = false
// if UserDefaults.enableMapRecentering {
// if latest.count == 1 {
// mapView.fit(annotations: showNodeHistory ? positions : latest, andShow: true)
// } else {
// mapView.fitAllAnnotations()
// }
// }
// } else {
// mapView.showsUserLocation = true
// }
// mapView.setUserTrackingMode(userTrackingMode, animated: true)
// }
// func makeCoordinator() -> MapCoordinator {
// return Coordinator(self)
// }
// final class MapCoordinator: NSObject, MKMapViewDelegate, UIGestureRecognizerDelegate {
// var parent: MapViewSwiftUI
// var longPressRecognizer = UILongPressGestureRecognizer()
// init(_ parent: MapViewSwiftUI) {
// self.parent = parent
// super.init()
// self.longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longPressHandler))
// self.longPressRecognizer.minimumPressDuration = 0.5
// self.longPressRecognizer.cancelsTouchesInView = true
// self.longPressRecognizer.delegate = self
// self.parent.mapView.addGestureRecognizer(longPressRecognizer)
// }
// func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
// switch annotation {
// case let positionAnnotation as PositionEntity:
// let reuseID = String(positionAnnotation.nodePosition?.num ?? 0) + "-" + String(positionAnnotation.time?.timeIntervalSince1970 ?? 0)
// let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "node") as? MKMarkerAnnotationView ?? MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: reuseID )
// annotationView.tag = -1
// annotationView.canShowCallout = true
// if positionAnnotation.latest {
// annotationView.markerTintColor = UIColor(hex: UInt32(positionAnnotation.nodePosition?.num ?? 0)).darker()
// annotationView.displayPriority = .required
// annotationView.titleVisibility = .visible
// } else {
// annotationView.markerTintColor = UIColor(hex: UInt32(positionAnnotation.nodePosition?.num ?? 0)).lighter()
// annotationView.displayPriority = .defaultHigh
// annotationView.titleVisibility = .adaptive
// }
// annotationView.tag = -1
// annotationView.canShowCallout = true
// annotationView.titleVisibility = .adaptive
// let leftIcon = UIImageView(image: annotationView.glyphText?.image())
// leftIcon.backgroundColor = UIColor(.indigo)
// annotationView.leftCalloutAccessoryView = leftIcon
// let subtitle = UILabel()
// subtitle.text = "Long Name: \(positionAnnotation.nodePosition?.user?.longName ?? "Unknown") \n"
// subtitle.text? += "Latitude: \(String(format: "%.5f", positionAnnotation.coordinate.latitude)) \n"
// subtitle.text! += "Longitude: \(String(format: "%.5f", positionAnnotation.coordinate.longitude)) \n"
// let distanceFormatter = MKDistanceFormatter()
// subtitle.text! += "Altitude: \(distanceFormatter.string(fromDistance: Double(positionAnnotation.altitude))) \n"
// if positionAnnotation.nodePosition?.metadata != nil {
// if DeviceRoles(rawValue: Int(positionAnnotation.nodePosition!.metadata?.role ?? 0)) == DeviceRoles.client ||
// DeviceRoles(rawValue: Int(positionAnnotation.nodePosition!.metadata?.role ?? 0)) == DeviceRoles.clientMute ||
// DeviceRoles(rawValue: Int(positionAnnotation.nodePosition!.metadata?.role ?? 0)) == DeviceRoles.routerClient {
// annotationView.glyphImage = UIImage(systemName: "flipphone")
// } else if DeviceRoles(rawValue: Int(positionAnnotation.nodePosition!.metadata?.role ?? 0)) == DeviceRoles.repeater {
// annotationView.glyphImage = UIImage(systemName: "repeat")
// } else if DeviceRoles(rawValue: Int(positionAnnotation.nodePosition!.metadata?.role ?? 0)) == DeviceRoles.router {
// annotationView.glyphImage = UIImage(systemName: "wifi.router.fill")
// } else if DeviceRoles(rawValue: Int(positionAnnotation.nodePosition!.metadata?.role ?? 0)) == DeviceRoles.tracker {
// annotationView.glyphImage = UIImage(systemName: "location.viewfinder")
// } else if DeviceRoles(rawValue: Int(positionAnnotation.nodePosition!.metadata?.role ?? 0)) == DeviceRoles.sensor {
// annotationView.glyphImage = UIImage(systemName: "sensor")
// }
// let pf = PositionFlags(rawValue: Int(positionAnnotation.nodePosition?.metadata?.positionFlags ?? 3))
// if pf.contains(.Satsinview) {
// subtitle.text! += "Sats in view: \(String(positionAnnotation.satsInView)) \n"
// }
// if pf.contains(.SeqNo) {
// subtitle.text! += "Sequence: \(String(positionAnnotation.seqNo)) \n"
// }
// if pf.contains(.Heading) {
// if parent.userTrackingMode != MKUserTrackingMode.followWithHeading {
// annotationView.glyphImage = UIImage(systemName: "location.north.fill")?.rotate(radians: Float(degreesToRadians(Double(positionAnnotation.heading))))
// subtitle.text! += "Heading: \(String(positionAnnotation.heading)) \n"
// } else {
// annotationView.glyphImage = UIImage(systemName: "flipphone")
// }
// }
// if pf.contains(.Speed) {
// let formatter = MeasurementFormatter()
// formatter.locale = Locale.current
// if positionAnnotation.speed <= 1 {
// annotationView.glyphImage = UIImage(systemName: "hexagon")
// }
// subtitle.text! += "Speed: \(formatter.string(from: Measurement(value: Double(positionAnnotation.speed), unit: UnitSpeed.kilometersPerHour))) \n"
// }
// } else {
// // node metadata is nil
// annotationView.glyphImage = UIImage(systemName: "flipphone")
// }
// if LocationHelper.currentLocation.distance(from: LocationHelper.DefaultLocation) > 0.0 {
// let metersAway = positionAnnotation.coordinate.distance(from: LocationHelper.currentLocation)
// subtitle.text! += "distance".localized + ": \(distanceFormatter.string(fromDistance: Double(metersAway))) \n"
// }
// subtitle.text! += positionAnnotation.time?.formatted() ?? "Unknown \n"
// subtitle.numberOfLines = 0
// annotationView.detailCalloutAccessoryView = subtitle
// let detailsIcon = UIButton(type: .detailDisclosure)
// detailsIcon.setImage(UIImage(systemName: "trash"), for: .normal)
// annotationView.rightCalloutAccessoryView = detailsIcon
// return annotationView
// case let waypointAnnotation as WaypointEntity:
// let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "waypoint") as? MKMarkerAnnotationView ?? MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: String(waypointAnnotation.id))
// annotationView.tag = Int(waypointAnnotation.id)
// annotationView.isEnabled = true
// annotationView.canShowCallout = true
// if waypointAnnotation.icon == 0 {
// annotationView.glyphText = "📍"
// } else {
// annotationView.glyphText = String(UnicodeScalar(Int(waypointAnnotation.icon)) ?? "📍")
// }
// annotationView.markerTintColor = UIColor(.accentColor)
// annotationView.displayPriority = .required
// annotationView.titleVisibility = .adaptive
// let leftIcon = UIImageView(image: annotationView.glyphText?.image())
// leftIcon.backgroundColor = UIColor(.accentColor)
// annotationView.leftCalloutAccessoryView = leftIcon
// let subtitle = UILabel()
// if waypointAnnotation.longDescription?.count ?? 0 > 0 {
// subtitle.text = (waypointAnnotation.longDescription ?? "") + "\n"
// } else {
// subtitle.text = ""
// }
// if LocationHelper.currentLocation.distance(from: LocationHelper.DefaultLocation) > 0.0 {
// let metersAway = waypointAnnotation.coordinate.distance(from: LocationHelper.currentLocation)
// let distanceFormatter = MKDistanceFormatter()
// subtitle.text! += "distance".localized + ": \(distanceFormatter.string(fromDistance: Double(metersAway))) \n"
// }
// if waypointAnnotation.created != nil {
// subtitle.text! += "Created: \(waypointAnnotation.created?.formatted() ?? "Unknown") \n"
// }
// if waypointAnnotation.lastUpdated != nil {
// subtitle.text! += "Updated: \(waypointAnnotation.lastUpdated?.formatted() ?? "Unknown") \n"
// }
// if waypointAnnotation.expire != nil {
// subtitle.text! += "Expires: \(waypointAnnotation.expire?.formatted() ?? "Unknown") \n"
// }
// subtitle.numberOfLines = 0
// annotationView.detailCalloutAccessoryView = subtitle
// let editIcon = UIButton(type: .detailDisclosure)
// editIcon.setImage(UIImage(systemName: "square.and.pencil"), for: .normal)
// annotationView.rightCalloutAccessoryView = editIcon
// return annotationView
// default: return nil
// }
// }
// func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
// switch view.annotation {
// case _ as WaypointEntity:
// // Only Allow Edit for waypoint annotations with a id
// if view.tag > 0 {
// parent.onWaypointEdit(view.tag)
// }
// default: break
// }
// }
// @objc func longPressHandler(_ gesture: UILongPressGestureRecognizer) {
// if gesture.state != UIGestureRecognizer.State.ended {
// return
// } else if gesture.state != UIGestureRecognizer.State.began {
// // Screen Position - CGPoint
// let location = longPressRecognizer.location(in: self.parent.mapView)
// // Map Coordinate - CLLocationCoordinate2D
// let coordinate = self.parent.mapView.convert(location, toCoordinateFrom: self.parent.mapView)
// let annotation = MKPointAnnotation()
// annotation.title = "Dropped Pin"
// annotation.coordinate = coordinate
// parent.mapView.addAnnotation(annotation)
// UINotificationFeedbackGenerator().notificationOccurred(.success)
// parent.onLongPress(coordinate)
// }
// }
// public func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
// if let tileOverlay = overlay as? MKTileOverlay {
// return MKTileOverlayRenderer(tileOverlay: tileOverlay)
// } else {
// if let routePolyline = overlay as? MKPolyline {
// let titleString = routePolyline.title ?? "0"
// let renderer = MKPolylineRenderer(polyline: routePolyline)
// renderer.strokeColor = UIColor(hex: UInt32(titleString) ?? 0).lighter()
// renderer.lineWidth = 8
// return renderer
// }
// if let polygon = overlay as? MKPolygon {
// let renderer = MKPolygonRenderer(polygon: polygon)
// renderer.fillColor = UIColor.purple.withAlphaComponent(0.2)
// renderer.strokeColor = .purple.withAlphaComponent(0.7)
// return renderer
// }
// return MKOverlayRenderer(overlay: overlay)
// }
// }
// }
// /// is supposed to be located in the folder with the map name
// public struct DefaultTile: Hashable {
// let tileName: String
// let tileType: String
// public init(tileName: String, tileType: String) {
// self.tileName = tileName
// self.tileType = tileType
// }
// }
// public struct CustomMapOverlay: Equatable, Hashable {
// let mapName: String
// let tileType: String
// var canReplaceMapContent: Bool
// var minimumZoomLevel: Int?
// var maximumZoomLevel: Int?
// let defaultTile: DefaultTile?
// public init(
// mapName: String,
// tileType: String,
// canReplaceMapContent: Bool = true, // false for transparent tiles
// minimumZoomLevel: Int? = nil,
// maximumZoomLevel: Int? = nil,
// defaultTile: DefaultTile? = nil
// ) {
// self.mapName = mapName
// self.tileType = tileType
// self.canReplaceMapContent = canReplaceMapContent
// self.minimumZoomLevel = minimumZoomLevel
// self.maximumZoomLevel = maximumZoomLevel
// self.defaultTile = defaultTile
// }
// public init?(
// mapName: String?,
// tileType: String,
// canReplaceMapContent: Bool = true, // false for transparent tiles
// minimumZoomLevel: Int? = nil,
// maximumZoomLevel: Int? = nil,
// defaultTile: DefaultTile? = nil
// ) {
// if mapName == nil || mapName! == "" {
// return nil
// }
// self.mapName = mapName!
// self.tileType = tileType
// self.canReplaceMapContent = canReplaceMapContent
// self.minimumZoomLevel = minimumZoomLevel
// self.maximumZoomLevel = maximumZoomLevel
// self.defaultTile = defaultTile
// }
// }
//}

View file

@ -1,14 +0,0 @@
import SwiftUI
struct TileDownloadStatus: View {
@ObservedObject var tileManager = OfflineTileManager.shared
var body: some View {
if tileManager.status == .downloading {
Image(systemName: "arrow.down.circle.fill")
.foregroundColor(.gray)
} else {
EmptyView()
}
}
}

View file

@ -1,164 +0,0 @@
////
//// NodeMapControl.swift
//// Meshtastic
////
//// Created by Garth Vander Houwen on 9/9/23.
////
//import SwiftUI
//import CoreLocation
//import MapKit
//import WeatherKit
//import OSLog
//
//struct NodeMapMapkit: View {
//
// @Environment(\.managedObjectContext) var context
// @EnvironmentObject var bleManager: BLEManager
// /// Weather
// /// The current weather condition for the city.
// @State private var condition: WeatherCondition?
// @State private var temperature: Measurement<UnitTemperature>?
// @State private var humidity: Int?
// @State private var symbolName: String = "cloud.fill"
// @State private var attributionLink: URL?
// @State private var attributionLogo: URL?
//
// @Environment(\.colorScheme) var colorScheme: ColorScheme
// @AppStorage("meshMapType") private var meshMapType = 0
// @AppStorage("meshMapShowNodeHistory") private var meshMapShowNodeHistory = false
// @AppStorage("meshMapShowRouteLines") private var meshMapShowRouteLines = false
// @State private var selectedMapLayer: MapLayer = .standard
// @State var waypointCoordinate: WaypointCoordinate?
// @State var editingWaypoint: Int = 0
// @State private var customMapOverlay: MapViewSwiftUI.CustomMapOverlay? = MapViewSwiftUI.CustomMapOverlay(
// mapName: "offlinemap",
// tileType: "png",
// canReplaceMapContent: true
// )
// @FetchRequest(sortDescriptors: [NSSortDescriptor(key: "name", ascending: false)],
// predicate: NSPredicate(
// format: "expire == nil || expire >= %@", Date() as NSDate
// ), animation: .none)
// private var waypoints: FetchedResults<WaypointEntity>
// @ObservedObject var node: NodeInfoEntity
//
// var body: some View {
//
// NavigationStack {
// GeometryReader { bounds in
// VStack {
// if node.hasPositions {
// ZStack {
// let positionArray = node.positions?.array as? [PositionEntity] ?? []
// let lastTenThousand = Array(positionArray.prefix(10000))
// // let todaysPositions = positionArray.filter { $0.time! >= Calendar.current.startOfDay(for: Date()) }
// ZStack {
// MapViewSwiftUI(onLongPress: { coord in
// waypointCoordinate = WaypointCoordinate(id: .init(), coordinate: coord, waypointId: 0)
// }, onWaypointEdit: { wpId in
// if wpId > 0 {
// waypointCoordinate = WaypointCoordinate(id: .init(), coordinate: nil, waypointId: Int64(wpId))
// }
// },
// selectedMapLayer: selectedMapLayer,
// positions: lastTenThousand,
// waypoints: Array(waypoints),
// userTrackingMode: MKUserTrackingMode.none,
// showNodeHistory: meshMapShowNodeHistory,
// showRouteLines: meshMapShowRouteLines,
// customMapOverlay: self.customMapOverlay
// )
// VStack(alignment: .leading) {
// Spacer()
// HStack(alignment: .bottom, spacing: 1) {
// Picker("Map Type", selection: $selectedMapLayer) {
// ForEach(MapLayer.allCases, id: \.self) { layer in
// if layer == MapLayer.offline && UserDefaults.enableOfflineMaps {
// Text(layer.localized)
// } else if layer != MapLayer.offline {
// Text(layer.localized)
// }
// }
// }
// .onChange(of: (selectedMapLayer)) { newMapLayer in
// UserDefaults.mapLayer = newMapLayer
// }
// .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 12, style: .continuous))
// .pickerStyle(.menu)
// .padding(5)
// VStack {
// VStack {
// Label(temperature?.formatted(.measurement(width: .narrow)) ?? "??", systemImage: symbolName)
// .font(.caption)
//
// Label("\(humidity ?? 0)%", systemImage: "humidity")
// .font(.caption2)
//
// AsyncImage(url: attributionLogo) { image in
// image
// .resizable()
// .scaledToFit()
// } placeholder: {
// ProgressView()
// .controlSize(.mini)
// }
// .frame(height: 10)
//
// Link("Other data sources", destination: attributionLink ?? URL(string: "https://weather-data.apple.com/legal-attribution.html")!)
// .font(.caption2)
// }
// .padding(5)
//
// }
// .background(.thinMaterial, in: RoundedRectangle(cornerRadius: 12, style: .continuous))
// .padding(5)
// .task {
// do {
// if node.hasPositions {
// let mostRecent = node.positions?.lastObject as? PositionEntity
// let weather = try await WeatherService.shared.weather(for: mostRecent?.nodeLocation ?? CLLocation(latitude: LocationHelper.currentLocation.latitude, longitude: LocationHelper.currentLocation.longitude))
// condition = weather.currentWeather.condition
// temperature = weather.currentWeather.temperature
// humidity = Int(weather.currentWeather.humidity * 100)
// symbolName = weather.currentWeather.symbolName
// let attribution = try await WeatherService.shared.attribution
// attributionLink = attribution.legalPageURL
// attributionLogo = colorScheme == .light ? attribution.combinedMarkLightURL : attribution.combinedMarkDarkURL
// }
// } catch {
// Logger.services.error("Could not gather weather information: \(error.localizedDescription)")
// condition = .clear
// symbolName = "cloud.fill"
// }
// }
// }
// }
// }
// .ignoresSafeArea(.all, edges: [.top, .leading, .trailing])
// .frame(idealWidth: bounds.size.width, minHeight: bounds.size.height / 1.65)
// }
// } else {
// HStack {
// }
// .padding([.top], 20)
// }
// }
// .edgesIgnoringSafeArea([.leading, .trailing])
// .sheet(item: $waypointCoordinate, content: { wpc in
// WaypointFormMapKit(coordinate: wpc)
// .presentationDetents([.medium, .large])
// .presentationDragIndicator(.automatic)
// })
// .navigationBarTitle(String(node.user?.longName ?? "unknown".localized), displayMode: .inline)
// .navigationBarItems(trailing:
// ZStack {
// ConnectedDevice(
// bluetoothOn: bleManager.isSwitchedOn,
// deviceConnected: bleManager.connectedPeripheral != nil,
// name: (bleManager.connectedPeripheral != nil) ? bleManager.connectedPeripheral.shortName : "?")
// })
// }
// .padding(.bottom, 2)
// }
// }
//}

View file

@ -1,266 +0,0 @@
////
//// WaypointFormView.swift
//// Meshtastic
////
//// Copyright Garth Vander Houwen 1/10/23.
////
//
//import CoreLocation
//import MeshtasticProtobufs
//import OSLog
//import SwiftUI
//
//struct WaypointFormMapKit: View {
//
// @EnvironmentObject var bleManager: BLEManager
// @Environment(\.dismiss) private var dismiss
// @State var coordinate: WaypointCoordinate
// @FocusState private var iconIsFocused: Bool
// @State private var name: String = ""
// @State private var description: String = ""
// @State private var icon: String = "📍"
// @State private var latitude: Double = 0
// @State private var longitude: Double = 0
// @State private var expires: Bool = false
// @State private var expire: Date = Date.now.addingTimeInterval(60 * 480) // 1 minute * 480 = 8 Hours
// @State private var locked: Bool = false
// @State private var lockedTo: Int64 = 0
//
// var body: some View {
//
// Form {
// let distance = CLLocation(latitude: LocationHelper.currentLocation.latitude, longitude: LocationHelper.currentLocation.longitude).distance(from: CLLocation(latitude: coordinate.coordinate?.latitude ?? 0, longitude: coordinate.coordinate?.longitude ?? 0))
// Section(header: Text((coordinate.waypointId > 0) ? "Editing Waypoint" : "Create Waypoint")) {
// HStack {
// Text("Location: \(String(format: "%.5f", latitude) + "," + String(format: "%.5f", longitude))")
// .textSelection(.enabled)
// .foregroundColor(Color.gray)
// .font(.caption2)
// if coordinate.coordinate?.latitude ?? 0 != 0 && coordinate.coordinate?.longitude ?? 0 != 0 {
// DistanceText(meters: distance)
// .foregroundColor(Color.gray)
// .font(.caption2)
// }
// }
// HStack {
// Text("Name")
// Spacer()
// TextField(
// "Name",
// text: $name,
// axis: .vertical
// )
// .foregroundColor(Color.gray)
// .onChange(of: name) {
// var totalBytes = name.utf8.count
// // Only mess with the value if it is too big
// while totalBytes > 30 {
// name = String(name.dropLast())
// totalBytes = name.utf8.count
// }
// if totalBytes > 30 {
// name = String(name.dropLast())
// }
// }
// }
// HStack {
// Text("Description")
// Spacer()
// TextField(
// "Description",
// text: $description,
// axis: .vertical
// )
// .foregroundColor(Color.gray)
// .onChange(of: description) {
// var totalBytes = description.utf8.count
// // Only mess with the value if it is too big
// while totalBytes > 100 {
// description = String(description.dropLast())
// totalBytes = description.utf8.count
// }
// }
// }
// HStack {
// Text("Icon")
// Spacer()
// EmojiOnlyTextField(text: $icon, placeholder: "Select an emoji")
// .font(.title)
// .focused($iconIsFocused)
// .onChange(of: icon) { _, value in
//
// // If you have anything other than emojis in your string make it empty
// if !value.onlyEmojis() {
// icon = ""
// }
// // If a second emoji is entered delete the first one
// if value.count >= 1 {
//
// if value.count > 1 {
// let index = value.index(value.startIndex, offsetBy: 1)
// icon = String(value[index])
// }
// iconIsFocused = false
// }
// }
//
// }
// Toggle(isOn: $expires) {
// Label("Expires", systemImage: "clock.badge.xmark")
// }
// .toggleStyle(SwitchToggleStyle(tint: .accentColor))
// if expires {
// DatePicker("Expire", selection: $expire, in: Date.now...)
// .datePickerStyle(.compact)
// .font(.callout)
// }
// Toggle(isOn: $locked) {
// Label("Locked", systemImage: "lock")
// }
// .toggleStyle(SwitchToggleStyle(tint: .accentColor))
// }
// }
// HStack {
// Button {
//
// var newWaypoint = Waypoint()
// // Loading a waypoint from edit
// if coordinate.waypointId > 0 {
// newWaypoint.id = UInt32(coordinate.waypointId)
// let waypoint = getWaypoint(id: Int64(coordinate.waypointId), context: bleManager.context)
// newWaypoint.latitudeI = waypoint.latitudeI
// newWaypoint.longitudeI = waypoint.longitudeI
// } else {
// // New waypoint
// newWaypoint.id = UInt32.random(in: UInt32(UInt8.max)..<UInt32.max)
// newWaypoint.latitudeI = Int32(Double(coordinate.coordinate?.latitude ?? 0) * 1e7)
// newWaypoint.longitudeI = Int32(Double(coordinate.coordinate?.longitude ?? 0) * 1e7)
// }
// newWaypoint.name = name.count > 0 ? name : "Dropped Pin"
// newWaypoint.description_p = description
// // Unicode scalar value for the icon emoji string
// let unicodeScalers = icon.unicodeScalars
// // First element as an UInt32
// let unicode = unicodeScalers[unicodeScalers.startIndex].value
// newWaypoint.icon = unicode
// if locked {
// if lockedTo == 0 {
// newWaypoint.lockedTo = UInt32(bleManager.connectedPeripheral!.num)
// } else {
// newWaypoint.lockedTo = UInt32(lockedTo)
// }
// }
// if expires {
// newWaypoint.expire = UInt32(expire.timeIntervalSince1970)
// } else {
// newWaypoint.expire = 0
// }
// if bleManager.sendWaypoint(waypoint: newWaypoint) {
// dismiss()
// } else {
// dismiss()
// Logger.mesh.error("Send waypoint failed")
// }
// } label: {
// Label("Send", systemImage: "arrow.up")
// }
// .buttonStyle(.bordered)
// .buttonBorderShape(.capsule)
// .controlSize(.regular)
// .disabled(bleManager.connectedPeripheral == nil)
// .padding(.bottom)
//
// Button(role: .cancel) {
// dismiss()
// } label: {
// Label("cancel", systemImage: "x.circle")
// }
// .buttonStyle(.bordered)
// .buttonBorderShape(.capsule)
// .controlSize(.regular)
// .padding(.bottom)
//
// if coordinate.waypointId > 0 {
//
// Menu {
// Button("For me", action: {
// let waypoint = getWaypoint(id: Int64(coordinate.waypointId), context: bleManager.context)
// bleManager.context.delete(waypoint)
// do {
// try bleManager.context.save()
// } catch {
// bleManager.context.rollback()
// }
// dismiss() })
// Button("For everyone", action: {
// var newWaypoint = Waypoint()
//
// if coordinate.waypointId > 0 {
// newWaypoint.id = UInt32(coordinate.waypointId)
// }
// newWaypoint.name = name.count > 0 ? name : "Dropped Pin"
// newWaypoint.description_p = description
// newWaypoint.latitudeI = Int32(coordinate.coordinate?.latitude ?? 0 * 1e7)
// newWaypoint.longitudeI = Int32(coordinate.coordinate?.longitude ?? 0 * 1e7)
// // Unicode scalar value for the icon emoji string
// let unicodeScalers = icon.unicodeScalars
// // First element as an UInt32
// let unicode = unicodeScalers[unicodeScalers.startIndex].value
// newWaypoint.icon = unicode
// if locked {
// if lockedTo == 0 {
// newWaypoint.lockedTo = UInt32(bleManager.connectedPeripheral!.num)
// } else {
// newWaypoint.lockedTo = UInt32(lockedTo)
// }
// }
// newWaypoint.expire = 1
// if bleManager.sendWaypoint(waypoint: newWaypoint) {
// dismiss()
// } else {
// dismiss()
// Logger.mesh.error("Send waypoint failed")
// }
// })
// }
// label: {
// Label("delete", systemImage: "trash")
// .foregroundColor(.red)
// }
// .buttonStyle(.bordered)
// .buttonBorderShape(.capsule)
// .controlSize(.regular)
// .padding(.bottom)
// }
// }
// .onAppear {
// if coordinate.waypointId > 0 {
// let waypoint = getWaypoint(id: Int64(coordinate.waypointId), context: bleManager.context)
// name = waypoint.name ?? "Dropped Pin"
// description = waypoint.longDescription ?? ""
// icon = String(UnicodeScalar(Int(waypoint.icon)) ?? "📍")
// latitude = Double(waypoint.latitudeI) / 1e7
// longitude = Double(waypoint.longitudeI) / 1e7
// if waypoint.expire != nil {
// expires = true
// expire = waypoint.expire ?? Date()
// } else {
// expires = false
// }
// if waypoint.locked > 0 {
// locked = true
// lockedTo = waypoint.locked
// }
// } else {
// name = ""
// description = ""
// locked = false
// expires = false
// expire = Date.now.addingTimeInterval(60 * 480)
// icon = "📍"
// latitude = coordinate.coordinate?.latitude ?? 0
// longitude = coordinate.coordinate?.longitude ?? 0
// }
// }
// }
//}

View file

@ -116,11 +116,11 @@ struct ChannelMessageList: View {
message.read = true
do {
try context.save()
Logger.data.info("📖 [App] Read message \(message.messageId) ")
Logger.data.info("📖 [App] Read message \(message.messageId, privacy: .public) ")
appState.unreadChannelMessages = myInfo.unreadMessages
context.refresh(myInfo, mergeChanges: true)
} catch {
Logger.data.error("Failed to read message \(message.messageId): \(error.localizedDescription)")
Logger.data.error("Failed to read message \(message.messageId, privacy: .public): \(error.localizedDescription, privacy: .public)")
}
}
}

View file

@ -79,7 +79,7 @@ struct MessageText: View {
do {
try context.save()
} catch {
Logger.data.error("Failed to delete message \(message.messageId): \(error.localizedDescription)")
Logger.data.error("Failed to delete message \(message.messageId, privacy: .public): \(error.localizedDescription, privacy: .public)")
}
}
Button("Cancel", role: .cancel) {}

View file

@ -37,7 +37,7 @@ struct RetryButton: View {
do {
try context.save()
} catch {
Logger.data.error("Failed to delete message \(messageID): \(error.localizedDescription)")
Logger.data.error("Failed to delete message \(messageID, privacy: .public): \(error.localizedDescription, privacy: .public)")
}
if !bleManager.sendMessage(
message: payload,
@ -47,7 +47,7 @@ struct RetryButton: View {
replyID: replyID
) {
// Best effort, unlikely since we already checked BLE state
Logger.services.warning("Failed to resend message \(messageID)")
Logger.services.warning("Failed to resend message \(messageID, privacy: .public)")
} else {
switch destination {
case .user:

View file

@ -31,10 +31,10 @@ struct TapbackResponses: View {
tapback.read = true
do {
try context.save()
Logger.data.info("📖 Read tapback \(tapback.messageId) ")
Logger.data.info("📖 Read tapback \(tapback.messageId, privacy: .public) ")
onRead()
} catch {
Logger.data.error("Failed to read tapback \(tapback.messageId): \(error.localizedDescription)")
Logger.data.error("Failed to read tapback \(tapback.messageId, privacy: .public): \(error.localizedDescription, privacy: .public)")
}
}
}

View file

@ -103,11 +103,11 @@ struct UserMessageList: View {
message.read = true
do {
try context.save()
Logger.data.info("📖 [App] Read message \(message.messageId) ")
Logger.data.info("📖 [App] Read message \(message.messageId, privacy: .public) ")
appState.unreadDirectMessages = user.unreadMessages
} catch {
Logger.data.error("Failed to read message \(message.messageId): \(error.localizedDescription)")
Logger.data.error("Failed to read message \(message.messageId, privacy: .public): \(error.localizedDescription, privacy: .public)")
}
}
}

View file

@ -135,7 +135,7 @@ struct DetectionSensorLog: View {
self.isExporting = false
Logger.services.info("Detection Sensor metrics log download succeeded.")
case .failure(let error):
Logger.services.error("Detection Sensor log download failed: \(error.localizedDescription).")
Logger.services.error("Detection Sensor log download failed: \(error.localizedDescription, privacy: .public).")
}
}
)

View file

@ -211,7 +211,7 @@ struct DeviceMetricsLog: View {
) {
Button("device.metrics.delete", role: .destructive) {
if clearTelemetry(destNum: node.num, metricsType: 0, context: context) {
Logger.data.notice("Cleared Device Metrics for \(node.num)")
Logger.data.notice("Cleared Device Metrics for \(node.num, privacy: .public)")
} else {
Logger.data.error("Clear Device Metrics Log Failed")
}
@ -257,7 +257,7 @@ struct DeviceMetricsLog: View {
self.isExporting = false
Logger.services.info("Device metrics log download succeeded.")
case .failure(let error):
Logger.services.error("Device metrics log download failed: \(error.localizedDescription)")
Logger.services.error("Device metrics log download failed: \(error.localizedDescription, privacy: .public)")
}
}
)

View file

@ -177,7 +177,7 @@ struct EnvironmentMetricsLog: View {
self.isExporting = false
Logger.services.info("Environment metrics log download succeeded.")
case .failure(let error):
Logger.services.error("Environment metrics log download failed: \(error.localizedDescription)")
Logger.services.error("Environment metrics log download failed: \(error.localizedDescription, privacy: .public)")
}
}
)

View file

@ -41,7 +41,7 @@ struct DeleteNodeButton: View {
id: node.num,
context: context
) else {
Logger.data.error("Unable to find node info to delete node \(node.num)")
Logger.data.error("Unable to find node info to delete node \(node.num, privacy: .public)")
return
}
let success = bleManager.removeNode(
@ -49,7 +49,7 @@ struct DeleteNodeButton: View {
connectedNodeNum: connectedNode.num
)
if !success {
Logger.data.error("Failed to delete node \(deleteNode.user?.longName ?? "unknown".localized)")
Logger.data.error("Failed to delete node \(deleteNode.user?.longName ?? "unknown".localized, privacy: .public)")
} else {
dismiss()
}

View file

@ -19,20 +19,20 @@ struct NavigateToButton: View {
Logger.services.error("NavigateToAction: Selected node does not exist")
return
}
Logger.services.info("Fetching NodeInfoEntity for userNum: \(userNum)")
Logger.services.info("Fetching NodeInfoEntity for userNum: \(userNum, privacy: .public)")
let fetchRequest: NSFetchRequest<NodeInfoEntity> = NSFetchRequest(entityName: "NodeInfoEntity")
fetchRequest.predicate = NSPredicate(format: "num == %lld", Int64(userNum))
do {
let fetchedNodes = try PersistenceController.shared.container.viewContext.fetch(fetchRequest)
guard let nodeInfo = fetchedNodes.first else {
Logger.services.error("NavigateToAction: Node with userNum \(userNum) not found in Core Data")
Logger.services.error("NavigateToAction: Node with userNum \(userNum, privacy: .public) not found in Core Data")
return
}
if let latitude = nodeInfo.latestPosition?.latitude,
let longitude = nodeInfo.latestPosition?.longitude {
if let url = URL(string: "maps://?saddr=&daddr=\(latitude),\(longitude)") {
@ -41,10 +41,10 @@ struct NavigateToButton: View {
Logger.services.error("Failed to create URL for navigation")
}
} else {
Logger.services.warning("NavigateToAction: Node \(userNum) has invalid or missing coordinates")
Logger.services.warning("NavigateToAction: Node \(userNum, privacy: .public) has invalid or missing coordinates")
}
} catch {
Logger.services.error("NavigateToAction: Failed to fetch node with userNum \(userNum): \(error.localizedDescription)")
Logger.services.error("NavigateToAction: Failed to fetch node with userNum \(userNum, privacy: .public): \(error.localizedDescription, privacy: .public)")
}
} label: {
Label {

View file

@ -115,7 +115,7 @@ struct MeshMap: View {
editingWaypoint!.longitudeI = Int32((newWaypointCoord?.longitude ?? 0) * 1e7)
editingWaypoint!.expire = Date.now.addingTimeInterval(60 * 480)
editingWaypoint!.id = 0
Logger.services.debug("Long press occured at Lat: \(coordinate.latitude) Long: \(coordinate.longitude)")
Logger.services.debug("Long press occured at Lat: \(coordinate.latitude, privacy: .public) Long: \(coordinate.longitude, privacy: .public)")
default: return
}
})

View file

@ -237,7 +237,7 @@ struct NodeList: View {
if deleteNode != nil {
let success = bleManager.removeNode(node: deleteNode!, connectedNodeNum: Int64(bleManager.connectedPeripheral?.num ?? -1))
if !success {
Logger.data.error("Failed to delete node \(deleteNode?.user?.longName ?? "unknown".localized)")
Logger.data.error("Failed to delete node \(deleteNode?.user?.longName ?? "unknown".localized, privacy: .public)")
}
}
}

View file

@ -176,7 +176,7 @@ struct PaxCounterLog: View {
) {
Button("paxcounter.delete", role: .destructive) {
if clearPax(destNum: node.num, context: context) {
Logger.services.info("Cleared Pax Counter for \(node.num)")
Logger.services.info("Cleared Pax Counter for \(node.num, privacy: .public)")
} else {
Logger.services.error("Clear Pax Counter Log Failed")
}
@ -216,7 +216,7 @@ struct PaxCounterLog: View {
self.isExporting = false
Logger.services.info("PAX Counter log download succeeded")
case .failure(let error):
Logger.services.error("PAX Counter log download failed: \(error.localizedDescription)")
Logger.services.error("PAX Counter log download failed: \(error.localizedDescription, privacy: .public)")
}
}
)

View file

@ -163,7 +163,7 @@ struct PositionLog: View {
Logger.services.info("Position log download succeeded.")
self.isExporting = false
case .failure(let error):
Logger.services.error("Position log download failed: \(error.localizedDescription)")
Logger.services.error("Position log download failed: \(error.localizedDescription, privacy: .public)")
}
}
)

View file

@ -243,7 +243,7 @@ struct PowerMetricsLog: View {
) {
Button("Delete Power metrics?", role: .destructive) {
if clearTelemetry(destNum: node.num, metricsType: 2, context: context) {
Logger.data.notice("Cleared Power Metrics for \(node.num)")
Logger.data.notice("Cleared Power Metrics for \(node.num, privacy: .public)")
} else {
Logger.data.error("Clear Power Metrics Log Failed")
}
@ -289,7 +289,7 @@ struct PowerMetricsLog: View {
self.isExporting = false
Logger.services.info("Power metrics log download succeeded.")
case .failure(let error):
Logger.services.error("Power metrics log download failed: \(error.localizedDescription)")
Logger.services.error("Power metrics log download failed: \(error.localizedDescription, privacy: .public)")
}
}
)

View file

@ -64,7 +64,7 @@ struct TraceRouteLog: View {
do {
try context.save()
} catch let error as NSError {
Logger.data.error("\(error.localizedDescription)")
Logger.data.error("\(error.localizedDescription, privacy: .public)")
}
} label: {
Label("delete", systemImage: "trash")

View file

@ -178,7 +178,7 @@ struct AppLog: View {
self.isExporting = false
Logger.services.info("Application log download succeeded.")
case .failure(let error):
Logger.services.error("Application log download failed: \(error.localizedDescription)")
Logger.services.error("Application log download failed: \(error.localizedDescription, privacy: .public)")
}
}
)

View file

@ -186,11 +186,11 @@ struct Channels: View {
if channel.role != Channel.Role.disabled {
do {
try context.save()
Logger.data.info("💾 Saved Channel: \(channel.settings.name)")
Logger.data.info("💾 Saved Channel: \(channel.settings.name, privacy: .public)")
} catch {
context.rollback()
let nsError = error as NSError
Logger.data.error("Unresolved Core Data error in the channel editor. Error: \(nsError)")
Logger.data.error("Unresolved Core Data error in the channel editor. Error: \(nsError, privacy: .public)")
}
} else {
let objects = selectedChannel?.allPrivateMessages ?? []
@ -203,11 +203,11 @@ struct Channels: View {
context.delete(selectedChannel!)
do {
try context.save()
Logger.data.info("💾 Deleted Channel: \(channel.settings.name)")
Logger.data.info("💾 Deleted Channel: \(channel.settings.name, privacy: .public)")
} catch {
context.rollback()
let nsError = error as NSError
Logger.data.error("Unresolved Core Data error in the channel editor. Error: \(nsError)")
Logger.data.error("Unresolved Core Data error in the channel editor. Error: \(nsError, privacy: .public)")
}
}
let adminMessageId = bleManager.saveChannel(channel: channel, fromUser: node!.user!, toUser: node!.user!)

View file

@ -249,7 +249,6 @@ struct LoRaConfig: View {
let expiration = node.sessionExpiration ?? Date()
if expiration < Date() || node.loRaConfig == nil {
Logger.mesh.info("⚙️ Empty or expired lora config requesting via PKI admin")
_ = bleManager.requestLoRaConfig(fromUser: connectedNode.user!, toUser: node.user!, adminIndex: connectedNode.myInfo?.adminIndex ?? 0)
}
} else {

View file

@ -357,7 +357,7 @@ struct MQTTConfig: View {
defaultTopic = "msh/" + (region?.topic ?? "UNSET")
geocoder.reverseGeocodeLocation(LocationsHandler.shared.locationsArray.first!, completionHandler: {(placemarks, error) in
if let error {
Logger.services.error("Failed to reverse geocode location: \(error.localizedDescription)")
Logger.services.error("Failed to reverse geocode location: \(error.localizedDescription, privacy: .public)")
return
}

View file

@ -117,7 +117,7 @@ struct StoreForwardConfig: View {
do {
try context.save()
} catch {
Logger.mesh.error("Failed to save isRouter: \(error.localizedDescription)")
Logger.mesh.error("Failed to save isRouter: \(error.localizedDescription, privacy: .public)")
}
}

View file

@ -530,7 +530,7 @@ struct PositionConfig: View {
} catch {
context.rollback()
let nsError = error as NSError
Logger.data.error("Error Saving Position Config Entity \(nsError)")
Logger.data.error("Error Saving Position Config Entity \(nsError, privacy: .public)")
}
}
@ -550,7 +550,7 @@ struct PositionConfig: View {
} catch {
context.rollback()
let nsError = error as NSError
Logger.data.error("Error Saving Position Config Entity \(nsError)")
Logger.data.error("Error Saving Position Config Entity \(nsError, privacy: .public)")
}
}
}

View file

@ -62,7 +62,7 @@ class Api: ObservableObject {
completion(deviceHardware)
}
} catch {
Logger.services.error("JSON decode failure: \(error.localizedDescription)")
Logger.services.error("JSON decode failure: \(error.localizedDescription, privacy: .public)")
}
return
}
@ -82,7 +82,7 @@ class Api: ObservableObject {
completion(firmwareReleases)
}
} catch {
Logger.services.error("JSON decode failure: \(error.localizedDescription)")
Logger.services.error("JSON decode failure: \(error.localizedDescription, privacy: .public)")
}
return
}

View file

@ -188,7 +188,7 @@ struct RouteRecorder: View {
} catch {
context.rollback()
let nsError = error as NSError
Logger.data.error("Error Saving RouteEntity from the Route Recorder \(nsError)")
Logger.data.error("Error Saving RouteEntity from the Route Recorder \(nsError, privacy: .public)")
}
} label: {
Label("start", systemImage: "play")
@ -246,7 +246,7 @@ struct RouteRecorder: View {
} catch {
context.rollback()
let nsError = error as NSError
Logger.data.error("Error Saving RouteEntity from the Route Recorder \(nsError)")
Logger.data.error("Error Saving RouteEntity from the Route Recorder \(nsError, privacy: .public)")
}
isShowingDetails = false
} label: {
@ -298,11 +298,10 @@ struct RouteRecorder: View {
do {
try context.save()
Logger.data.info("💾 Saved a new route location")
// logger.info("💾 Updated Canned Messages Messages For: \(fetchedNode[0].num)")
} catch {
context.rollback()
let nsError = error as NSError
Logger.data.error("Error Saving LocationEntity from the Route Recorder \(nsError)")
Logger.data.error("Error Saving LocationEntity from the Route Recorder \(nsError, privacy: .public)")
}
}
}

View file

@ -64,7 +64,7 @@ struct Routes: View {
var latIndex = -1
var longIndex = -1
for index in headers!.indices {
Logger.services.debug("\(index): \( headers![index])")
Logger.services.debug("\(index, privacy: .public): \( headers![index], privacy: .public)")
if headers![index].trimmingCharacters(in: .whitespaces) == "Latitude" {
latIndex = index
} else if headers![index].trimmingCharacters(in: .whitespaces) == "Longitude" {
@ -94,7 +94,7 @@ struct Routes: View {
do {
try context.save()
} catch let error as NSError {
Logger.services.error("\(error.localizedDescription)")
Logger.services.error("\(error.localizedDescription, privacy: .public)")
isShowingBadFileAlert = true
}
} else {
@ -103,11 +103,11 @@ struct Routes: View {
} catch {
// TODO: deal with errors
Logger.services.error("\(error.localizedDescription)")
Logger.services.error("\(error.localizedDescription, privacy: .public)")
}
} catch {
Logger.services.error("CSV Import Error: \(error.localizedDescription)")
Logger.services.error("CSV Import Error: \(error.localizedDescription, privacy: .public)")
}
}
List(routes, id: \.self, selection: $selectedRoute) { route in
@ -151,7 +151,7 @@ struct Routes: View {
do {
try context.save()
} catch let error as NSError {
Logger.data.error("\(error.localizedDescription)")
Logger.data.error("\(error.localizedDescription, privacy: .public)")
}
} label: {
Label("delete", systemImage: "trash")
@ -227,7 +227,7 @@ struct Routes: View {
} catch {
context.rollback()
let nsError = error as NSError
Logger.data.error("Error Saving RouteEntity from the Route Editor \(nsError)")
Logger.data.error("Error Saving RouteEntity from the Route Editor \(nsError, privacy: .public)")
}
}
.buttonStyle(.bordered)
@ -300,7 +300,7 @@ struct Routes: View {
self.isExporting = false
Logger.services.info("Route log download succeeded.")
case .failure(let error):
Logger.services.error("Route log download failed: \(error.localizedDescription).")
Logger.services.error("Route log download failed: \(error.localizedDescription, privacy: .public).")
}
}
)