From a4d5aefca376aa377917f3c2263b9c5bf13052a7 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Sat, 5 Oct 2024 15:50:57 -0700 Subject: [PATCH] Bossy linter --- Meshtastic/AppIntents/AppIntentErrors.swift | 2 +- .../AppIntents/FactoryResetNodeIntent.swift | 6 +- .../AppIntents/MessageChannelIntent.swift | 2 +- .../AppIntents/NodePositionIntent.swift | 62 +++++++++---------- Meshtastic/Enums/TelemetryEnums.swift | 1 - Meshtastic/Helpers/BLEManager.swift | 56 +++++++---------- .../Helpers/LocalNotificationManager.swift | 18 ++---- Meshtastic/Helpers/MeshPackets.swift | 14 ++--- Meshtastic/MeshtasticApp.swift | 2 +- Meshtastic/MeshtasticAppDelegate.swift | 3 - Meshtastic/Persistence/UpdateCoreData.swift | 8 +-- Meshtastic/Views/Bluetooth/Connect.swift | 4 +- Meshtastic/Views/ContentView.swift | 2 +- .../Views/MapKitMap/WaypointFormMapKit.swift | 4 +- .../Views/Messages/ChannelMessageList.swift | 4 +- Meshtastic/Views/Messages/Messages.swift | 2 +- .../TextMessageField/TextMessageField.swift | 4 +- Meshtastic/Views/Messages/UserList.swift | 16 ++--- .../Views/Messages/UserMessageList.swift | 4 +- Meshtastic/Views/Nodes/DeviceMetricsLog.swift | 2 +- .../Nodes/Helpers/Map/MapSettingsForm.swift | 4 +- .../Nodes/Helpers/Map/NodeMapSwiftUI.swift | 2 +- .../Nodes/Helpers/Map/PositionPopover.swift | 1 - Meshtastic/Views/Nodes/NodeList.swift | 18 +++--- Meshtastic/Views/Settings/AppData.swift | 2 - Meshtastic/Views/Settings/AppLog.swift | 8 +-- .../Views/Settings/Channels/ChannelForm.swift | 30 ++++----- .../Settings/Config/BluetoothConfig.swift | 4 +- .../Views/Settings/Config/DeviceConfig.swift | 2 +- .../Config/Module/CannedMessagesConfig.swift | 5 +- .../Settings/Config/Module/MQTTConfig.swift | 16 ++--- .../Config/Module/PaxCounterConfig.swift | 8 +-- .../Config/Module/StoreForwardConfig.swift | 24 +++---- .../Views/Settings/Config/NetworkConfig.swift | 12 ++-- .../Settings/Config/PositionConfig.swift | 2 +- .../Views/Settings/Config/PowerConfig.swift | 4 +- .../Settings/Config/SecurityConfig.swift | 6 +- Meshtastic/Views/Settings/RouteRecorder.swift | 2 +- Meshtastic/Views/Settings/Routes.swift | 13 ++-- Meshtastic/Views/Settings/Settings.swift | 7 +-- Meshtastic/Views/Settings/ShareChannels.swift | 18 +++--- Meshtastic/Views/Settings/UserConfig.swift | 18 +++--- Widgets/WidgetsLiveActivity.swift | 1 - 43 files changed, 191 insertions(+), 232 deletions(-) diff --git a/Meshtastic/AppIntents/AppIntentErrors.swift b/Meshtastic/AppIntents/AppIntentErrors.swift index 8e80b6b6..427c30ae 100644 --- a/Meshtastic/AppIntents/AppIntentErrors.swift +++ b/Meshtastic/AppIntents/AppIntentErrors.swift @@ -15,7 +15,7 @@ class AppIntentErrors { var localizedStringResource: LocalizedStringResource { switch self { - case let .message(message): + case let .message(message): Logger.services.error("App Intent: \(message)") return "Error: \(message)" case .notConnected: diff --git a/Meshtastic/AppIntents/FactoryResetNodeIntent.swift b/Meshtastic/AppIntents/FactoryResetNodeIntent.swift index 7ff2bd92..60946b00 100644 --- a/Meshtastic/AppIntents/FactoryResetNodeIntent.swift +++ b/Meshtastic/AppIntents/FactoryResetNodeIntent.swift @@ -11,10 +11,10 @@ import AppIntents struct FactoryResetNodeIntent: AppIntent { static var title: LocalizedStringResource = "Factory Reset" static var description: IntentDescription = "Perform a factory reset on the node you are connected to" - + func perform() async throws -> some IntentResult { // Request user confirmation before performing the factory reset - try await requestConfirmation(result: .result(dialog: "Are you sure you want to factory reset the node?"),confirmationActionName: ConfirmationActionName + try await requestConfirmation(result: .result(dialog: "Are you sure you want to factory reset the node?"), confirmationActionName: ConfirmationActionName .custom(acceptLabel: "Factory Reset", acceptAlternatives: [], denyLabel: "Cancel", denyAlternatives: [], destructive: true)) // Ensure the node is connected @@ -27,7 +27,7 @@ struct FactoryResetNodeIntent: AppIntent { let connectedNode = getNodeInfo(id: connectedPeripheralNum, context: PersistenceController.shared.container.viewContext), let fromUser = connectedNode.user, let toUser = connectedNode.user { - + // Attempt to send a factory reset command, throw an error if it fails if !BLEManager.shared.sendFactoryReset(fromUser: fromUser, toUser: toUser) { throw AppIntentErrors.AppIntentError.message("Failed to perform factory reset") diff --git a/Meshtastic/AppIntents/MessageChannelIntent.swift b/Meshtastic/AppIntents/MessageChannelIntent.swift index e387e17c..aa9ea47a 100644 --- a/Meshtastic/AppIntents/MessageChannelIntent.swift +++ b/Meshtastic/AppIntents/MessageChannelIntent.swift @@ -36,7 +36,7 @@ struct MessageChannelIntent: AppIntent { guard let messageData = messageContent.data(using: .utf8) else { throw AppIntentErrors.AppIntentError.message("Failed to encode message content") } - + if messageData.count > 200 { throw $messageContent.needsValueError("Message content exceeds 200 bytes.") } diff --git a/Meshtastic/AppIntents/NodePositionIntent.swift b/Meshtastic/AppIntents/NodePositionIntent.swift index a173df0d..1e052eb9 100644 --- a/Meshtastic/AppIntents/NodePositionIntent.swift +++ b/Meshtastic/AppIntents/NodePositionIntent.swift @@ -14,44 +14,38 @@ struct NodePositionIntent: AppIntent { @Parameter(title: "Node Number") var nodeNum: Int - + static var title: LocalizedStringResource = "Get Node Position" static var description: IntentDescription = "Fetch the latest position of a cetain node" - - + func perform() async throws -> some IntentResult & ReturnsValue { - if (!BLEManager.shared.isConnected) { + if !BLEManager.shared.isConnected { throw AppIntentErrors.AppIntentError.notConnected } - let fetchNodeInfoRequest: NSFetchRequest = NSFetchRequest(entityName: "NodeInfoEntity") - fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum)) - do { - guard let fetchedNode = try PersistenceController.shared.container.viewContext.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity], fetchedNode.count == 1 else { - throw $nodeNum.needsValueError("Could not find node") - } - - let nodeInfo = fetchedNode[0] - nodeInfo.latestEnvironmentMetrics?.batteryLevel - if let latitude = nodeInfo.latestPosition?.coordinate.latitude, - let longitude = nodeInfo.latestPosition?.coordinate.longitude { - let nodeLocation = CLLocation(latitude: latitude, longitude: longitude) - - // Reverse geocode the CLLocation to get a CLPlacemark - let geocoder = CLGeocoder() - let placemarks = try await geocoder.reverseGeocodeLocation(nodeLocation) - - if let placemark = placemarks.first { - return .result(value: placemark) - } else { - throw AppIntentErrors.AppIntentError.message("Error Reverse Geocoding Location") - } - } else { - throw AppIntentErrors.AppIntentError.message("Node does not have positions") - } - } catch { - throw AppIntentErrors.AppIntentError.message("Fetch Failure") + let fetchNodeInfoRequest: NSFetchRequest = NSFetchRequest(entityName: "NodeInfoEntity") + fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum)) + do { + guard let fetchedNode = try PersistenceController.shared.container.viewContext.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity], fetchedNode.count == 1 else { + throw $nodeNum.needsValueError("Could not find node") } - } - -} + let nodeInfo = fetchedNode[0] + if let latitude = nodeInfo.latestPosition?.coordinate.latitude, + let longitude = nodeInfo.latestPosition?.coordinate.longitude { + let nodeLocation = CLLocation(latitude: latitude, longitude: longitude) + // Reverse geocode the CLLocation to get a CLPlacemark + let geocoder = CLGeocoder() + let placemarks = try await geocoder.reverseGeocodeLocation(nodeLocation) + if let placemark = placemarks.first { + return .result(value: placemark) + } else { + throw AppIntentErrors.AppIntentError.message("Error Reverse Geocoding Location") + } + } else { + throw AppIntentErrors.AppIntentError.message("Node does not have positions") + } + } catch { + throw AppIntentErrors.AppIntentError.message("Fetch Failure") + } + } +} diff --git a/Meshtastic/Enums/TelemetryEnums.swift b/Meshtastic/Enums/TelemetryEnums.swift index 8de53403..213d6963 100644 --- a/Meshtastic/Enums/TelemetryEnums.swift +++ b/Meshtastic/Enums/TelemetryEnums.swift @@ -177,7 +177,6 @@ enum Iaq: Int, CaseIterable, Identifiable { } } - // Default of 0 is Client enum MetricsTypes: Int, CaseIterable, Identifiable { diff --git a/Meshtastic/Helpers/BLEManager.swift b/Meshtastic/Helpers/BLEManager.swift index 50e13f28..805f32a2 100644 --- a/Meshtastic/Helpers/BLEManager.swift +++ b/Meshtastic/Helpers/BLEManager.swift @@ -54,31 +54,28 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate let LOGRADIO_UUID = CBUUID(string: "0x5a3d6e49-06e6-4423-9944-e9de8cdf9547") // MARK: init - private override init() { - // Default initialization should not be used - fatalError("Use setup(appState:context:) to initialize the singleton") - } + // Default initialization should not be used + fatalError("Use setup(appState:context:) to initialize the singleton") + } - static func setup(appState: AppState, context: NSManagedObjectContext) { - guard shared == nil else { - print("BLEManager already initialized") - return - } - shared = BLEManager(appState: appState, context: context) + static func setup(appState: AppState, context: NSManagedObjectContext) { + guard shared == nil else { + Logger.services.warning("[BLE] BLEManager already initialized") + return } + shared = BLEManager(appState: appState, context: context) + } - private init(appState: AppState, context: NSManagedObjectContext) { - self.appState = appState - self.context = context - self.lastConnectionError = "" - self.connectedVersion = "0.0.0" - super.init() - centralManager = CBCentralManager(delegate: self, queue: nil) - mqttManager.delegate = self - } - - + private init(appState: AppState, context: NSManagedObjectContext) { + self.appState = appState + self.context = context + self.lastConnectionError = "" + self.connectedVersion = "0.0.0" + super.init() + centralManager = CBCentralManager(delegate: self, queue: nil) + mqttManager.delegate = self + } // MARK: Scanning for BLE Devices // Scan for nearby BLE devices using the Meshtastic BLE service ID @@ -464,7 +461,6 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate do { let fetchedNodes = try context.fetch(nodes) let receivingNode = fetchedNodes.first(where: { $0.num == destNum }) - let connectedNode = fetchedNodes.first(where: { $0.num == self.connectedPeripheral.num }) traceRoute.id = Int64(meshPacket.id) traceRoute.time = Date() traceRoute.node = receivingNode @@ -1617,7 +1613,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate let decodedString = base64UrlString.base64urlToBase64() if let decodedData = Data(base64Encoded: decodedString) { do { - let channelSet: ChannelSet = try ChannelSet(serializedData: decodedData) + let channelSet: ChannelSet = try ChannelSet(serializedBytes: decodedData) for cs in channelSet.settings { if addChannels { // We are trying to add a channel so lets get the last index @@ -1989,10 +1985,9 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate let messageDescription = "🛟 Saved LoRa Config for \(toUser.longName ?? "unknown".localized)" if sendAdminMessageToRadio(meshPacket: meshPacket, adminDescription: messageDescription) { - upsertLoRaConfigPacket(config: config, nodeNum: toUser.num, sessionPasskey: toUser.userNode?.sessionPasskey,context: context) + upsertLoRaConfigPacket(config: config, nodeNum: toUser.num, sessionPasskey: toUser.userNode?.sessionPasskey, context: context) return Int64(meshPacket.id) } - return 0 } @@ -3195,7 +3190,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate } func storeAndForwardPacket(packet: MeshPacket, connectedNodeNum: Int64, context: NSManagedObjectContext) { - if let storeAndForwardMessage = try? StoreAndForward(serializedData: packet.decoded.payload) { + if let storeAndForwardMessage = try? StoreAndForward(serializedBytes: packet.decoded.payload) { // Handle each of the store and forward request / response messages switch storeAndForwardMessage.rr { case .unset: @@ -3321,7 +3316,7 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate // MARK: - CB Central Manager implmentation extension BLEManager: CBCentralManagerDelegate { - + // MARK: Bluetooth enabled/disabled func centralManagerDidUpdateState(_ central: CBCentralManager) { if central.state == CBManagerState.poweredOn { @@ -3331,9 +3326,8 @@ extension BLEManager: CBCentralManagerDelegate { } else { isSwitchedOn = false } - + var status = "" - switch central.state { case .poweredOff: status = "BLE is powered off" @@ -3352,10 +3346,9 @@ extension BLEManager: CBCentralManagerDelegate { } Logger.services.info("📜 [BLE] Bluetooth status: \(status)") } - + // Called each time a peripheral is discovered func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber) { - if self.automaticallyReconnect && peripheral.identifier.uuidString == UserDefaults.standard.object(forKey: "preferredPeripheralId") as? String ?? "" { self.connectTo(peripheral: peripheral) Logger.services.info("✅ [BLE] Reconnecting to prefered peripheral: \(peripheral.name ?? "Unknown", privacy: .public)") @@ -3363,7 +3356,6 @@ extension BLEManager: CBCentralManagerDelegate { let name = advertisementData[CBAdvertisementDataLocalNameKey] as? String let device = Peripheral(id: peripheral.identifier.uuidString, num: 0, name: name ?? "Unknown", shortName: "?", longName: name ?? "Unknown", firmwareVersion: "Unknown", rssi: RSSI.intValue, lastUpdate: Date(), peripheral: peripheral) let index = peripherals.map { $0.peripheral }.firstIndex(of: peripheral) - if let peripheralIndex = index { peripherals[peripheralIndex] = device } else { diff --git a/Meshtastic/Helpers/LocalNotificationManager.swift b/Meshtastic/Helpers/LocalNotificationManager.swift index 1260f20c..47f64bce 100644 --- a/Meshtastic/Helpers/LocalNotificationManager.swift +++ b/Meshtastic/Helpers/LocalNotificationManager.swift @@ -5,16 +5,9 @@ import OSLog class LocalNotificationManager { var notifications = [Notification]() - - let thumbsUpAction = UNNotificationAction(identifier: "messageNotification.thumbsUpAction", title: - "👍 \(Tapbacks.thumbsUp.description)", options: []) - let thumbsDownAction = UNNotificationAction(identifier: "messageNotification.thumbsDownAction", title: - "👎 \(Tapbacks.thumbsDown.description)", options: []) - let replyInputAction = UNTextInputNotificationAction( - identifier: "messageNotification.replyInputAction", - title: "reply".localized, - options: []) - + let thumbsUpAction = UNNotificationAction(identifier: "messageNotification.thumbsUpAction", title: "👍 \(Tapbacks.thumbsUp.description)", options: []) + let thumbsDownAction = UNNotificationAction(identifier: "messageNotification.thumbsDownAction", title: "👎 \(Tapbacks.thumbsDown.description)", options: []) + let replyInputAction = UNTextInputNotificationAction(identifier: "messageNotification.replyInputAction", title: "reply".localized, options: []) // Step 1 Request Permissions for notifications private func requestAuthorization() { @@ -43,13 +36,13 @@ class LocalNotificationManager { private func scheduleNotifications() { let messageNotificationCategory = UNNotificationCategory( identifier: "messageNotificationCategory", - actions: [thumbsUpAction, thumbsDownAction,replyInputAction], + actions: [thumbsUpAction, thumbsDownAction, replyInputAction], intentIdentifiers: [], options: .customDismissAction ) UNUserNotificationCenter.current().setNotificationCategories([messageNotificationCategory]) - + for notification in notifications { let content = UNMutableNotificationContent() content.subtitle = notification.subtitle @@ -75,7 +68,6 @@ class LocalNotificationManager { content.userInfo["userNum"] = notification.userNum } - let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false) let request = UNNotificationRequest(identifier: notification.id, content: content, trigger: trigger) diff --git a/Meshtastic/Helpers/MeshPackets.swift b/Meshtastic/Helpers/MeshPackets.swift index 7d0c6a6b..9c4ed69c 100644 --- a/Meshtastic/Helpers/MeshPackets.swift +++ b/Meshtastic/Helpers/MeshPackets.swift @@ -50,7 +50,6 @@ func generateMessageMarkdown (message: String) -> String { func localConfig (config: Config, context: NSManagedObjectContext, nodeNum: Int64, nodeLongName: String) { - let remote = nodeNum != UserDefaults.preferredPeripheralNum if config.payloadVariant == Config.OneOf_PayloadVariant.bluetooth(config.bluetooth) { upsertBluetoothConfigPacket(config: config.bluetooth, nodeNum: nodeNum, context: context) } else if config.payloadVariant == Config.OneOf_PayloadVariant.device(config.device) { @@ -454,11 +453,11 @@ func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObje func adminAppPacket (packet: MeshPacket, context: NSManagedObjectContext) { - if let adminMessage = try? AdminMessage(serializedData: packet.decoded.payload) { + if let adminMessage = try? AdminMessage(serializedBytes: packet.decoded.payload) { if adminMessage.payloadVariant == AdminMessage.OneOf_PayloadVariant.getCannedMessageModuleMessagesResponse(adminMessage.getCannedMessageModuleMessagesResponse) { - if let cmmc = try? CannedMessageModuleConfig(serializedData: packet.decoded.payload) { + if let cmmc = try? CannedMessageModuleConfig(serializedBytes: packet.decoded.payload) { if !cmmc.messages.isEmpty { @@ -581,7 +580,7 @@ func paxCounterPacket (packet: MeshPacket, context: NSManagedObjectContext) { do { let fetchedNode = try context.fetch(fetchNodeInfoRequest) - if let paxMessage = try? Paxcount(serializedData: packet.decoded.payload) { + if let paxMessage = try? Paxcount(serializedBytes: packet.decoded.payload) { let newPax = PaxCounterEntity(context: context) newPax.ble = Int32(truncatingIfNeeded: paxMessage.ble) @@ -611,7 +610,7 @@ func paxCounterPacket (packet: MeshPacket, context: NSManagedObjectContext) { func routingPacket (packet: MeshPacket, connectedNodeNum: Int64, context: NSManagedObjectContext) { - if let routingMessage = try? Routing(serializedData: packet.decoded.payload) { + if let routingMessage = try? Routing(serializedBytes: packet.decoded.payload) { let routingError = RoutingError(rawValue: routingMessage.errorReason.rawValue) @@ -833,7 +832,7 @@ func textMessageAppPacket( } var storeForwardBroadcast = false if storeForward { - if let storeAndForwardMessage = try? StoreAndForward(serializedData: packet.decoded.payload) { + if let storeAndForwardMessage = try? StoreAndForward(serializedBytes: packet.decoded.payload) { messageText = String(bytes: storeAndForwardMessage.text, encoding: .utf8) if storeAndForwardMessage.rr == .routerTextBroadcast { storeForwardBroadcast = true @@ -993,7 +992,6 @@ func textMessageAppPacket( } } - func waypointPacket (packet: MeshPacket, context: NSManagedObjectContext) { let logString = String.localizedStringWithFormat("mesh.log.waypoint.received %@".localized, String(packet.from)) @@ -1004,7 +1002,7 @@ func waypointPacket (packet: MeshPacket, context: NSManagedObjectContext) { do { - if let waypointMessage = try? Waypoint(serializedData: packet.decoded.payload) { + if let waypointMessage = try? Waypoint(serializedBytes: packet.decoded.payload) { let fetchedWaypoint = try context.fetch(fetchWaypointRequest) if fetchedWaypoint.isEmpty { let waypoint = WaypointEntity(context: context) diff --git a/Meshtastic/MeshtasticApp.swift b/Meshtastic/MeshtasticApp.swift index 2c5a55ee..b7b28f35 100644 --- a/Meshtastic/MeshtasticApp.swift +++ b/Meshtastic/MeshtasticApp.swift @@ -125,7 +125,7 @@ struct MeshtasticAppleApp: App { ) } } - .onChange(of: scenePhase) { (newScenePhase) in + .onChange(of: scenePhase) { (_, newScenePhase) in switch newScenePhase { case .background: Logger.services.info("🎬 [App] Scene is in the background") diff --git a/Meshtastic/MeshtasticAppDelegate.swift b/Meshtastic/MeshtasticAppDelegate.swift index 87226052..801fa955 100644 --- a/Meshtastic/MeshtasticAppDelegate.swift +++ b/Meshtastic/MeshtasticAppDelegate.swift @@ -61,7 +61,6 @@ class MeshtasticAppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificat } else { Logger.services.error("Failed to retrieve channel or messageId from userInfo") } - break case "messageNotification.thumbsDownAction": if let channel = userInfo["channel"] as? Int32, let replyID = userInfo["messageId"] as? Int64 { @@ -76,7 +75,6 @@ class MeshtasticAppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificat } else { Logger.services.error("Failed to retrieve channel or messageId from userInfo") } - break case "messageNotification.replyInputAction": if let userInput = (response as? UNTextInputNotificationResponse)?.userText, let channel = userInfo["channel"] as? Int32, @@ -92,7 +90,6 @@ class MeshtasticAppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificat } else { Logger.services.error("Failed to retrieve user input, channel, or messageId from userInfo") } - break default: break } diff --git a/Meshtastic/Persistence/UpdateCoreData.swift b/Meshtastic/Persistence/UpdateCoreData.swift index fc8eac8e..69757588 100644 --- a/Meshtastic/Persistence/UpdateCoreData.swift +++ b/Meshtastic/Persistence/UpdateCoreData.swift @@ -159,12 +159,12 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext) if packet.to == Constants.maximumNodeNum || packet.to == UserDefaults.preferredPeripheralNum { newNode.channel = Int32(packet.channel) } - if let nodeInfoMessage = try? NodeInfo(serializedData: packet.decoded.payload) { + if let nodeInfoMessage = try? NodeInfo(serializedBytes: packet.decoded.payload) { newNode.hopsAway = Int32(nodeInfoMessage.hopsAway) newNode.favorite = nodeInfoMessage.isFavorite } - if let newUserMessage = try? User(serializedData: packet.decoded.payload) { + if let newUserMessage = try? User(serializedBytes: packet.decoded.payload) { if newUserMessage.id.isEmpty { if packet.from > Constants.minimumNodeNum { @@ -254,7 +254,7 @@ func upsertNodeInfoPacket (packet: MeshPacket, context: NSManagedObjectContext) fetchedNode[0].channel = Int32(packet.channel) } - if let nodeInfoMessage = try? NodeInfo(serializedData: packet.decoded.payload) { + if let nodeInfoMessage = try? NodeInfo(serializedBytes: packet.decoded.payload) { fetchedNode[0].hopsAway = Int32(nodeInfoMessage.hopsAway) fetchedNode[0].favorite = nodeInfoMessage.isFavorite @@ -320,7 +320,7 @@ func upsertPositionPacket (packet: MeshPacket, context: NSManagedObjectContext) do { - if let positionMessage = try? Position(serializedData: packet.decoded.payload) { + if let positionMessage = try? Position(serializedBytes: packet.decoded.payload) { /// Don't save empty position packets from null island or apple park if (positionMessage.longitudeI != 0 && positionMessage.latitudeI != 0) && (positionMessage.latitudeI != 373346000 && positionMessage.longitudeI != -1220090000) { diff --git a/Meshtastic/Views/Bluetooth/Connect.swift b/Meshtastic/Views/Bluetooth/Connect.swift index 5bda12df..c26b7676 100644 --- a/Meshtastic/Views/Bluetooth/Connect.swift +++ b/Meshtastic/Views/Bluetooth/Connect.swift @@ -301,10 +301,10 @@ struct Connect: View { .presentationDetents([.large]) .presentationDragIndicator(.automatic) } - .onChange(of: (self.bleManager.invalidVersion)) { _ in + .onChange(of: self.bleManager.invalidVersion) { invalidFirmwareVersion = self.bleManager.invalidVersion } - .onChange(of: (self.bleManager.isSubscribed)) { sub in + .onChange(of: self.bleManager.isSubscribed) { _, sub in if UserDefaults.preferredPeripheralId.count > 0 && sub { diff --git a/Meshtastic/Views/ContentView.swift b/Meshtastic/Views/ContentView.swift index cb5032ee..b122b0aa 100644 --- a/Meshtastic/Views/ContentView.swift +++ b/Meshtastic/Views/ContentView.swift @@ -43,7 +43,7 @@ struct ContentView: View { Label("map", systemImage: "map") } .tag(NavigationState.Tab.map) - + Settings( router: appState.router ) diff --git a/Meshtastic/Views/MapKitMap/WaypointFormMapKit.swift b/Meshtastic/Views/MapKitMap/WaypointFormMapKit.swift index 5fc5e2f4..f2451a28 100644 --- a/Meshtastic/Views/MapKitMap/WaypointFormMapKit.swift +++ b/Meshtastic/Views/MapKitMap/WaypointFormMapKit.swift @@ -51,7 +51,7 @@ struct WaypointFormMapKit: View { axis: .vertical ) .foregroundColor(Color.gray) - .onChange(of: name, perform: { _ in + .onChange(of: name) { var totalBytes = name.utf8.count // Only mess with the value if it is too big while totalBytes > 30 { @@ -61,7 +61,7 @@ struct WaypointFormMapKit: View { if totalBytes > 30 { name = String(name.dropLast()) } - }) + } } HStack { Text("Description") diff --git a/Meshtastic/Views/Messages/ChannelMessageList.swift b/Meshtastic/Views/Messages/ChannelMessageList.swift index 36cc5592..1b783427 100644 --- a/Meshtastic/Views/Messages/ChannelMessageList.swift +++ b/Meshtastic/Views/Messages/ChannelMessageList.swift @@ -134,11 +134,11 @@ struct ChannelMessageList: View { scrollView.scrollTo(channel.allPrivateMessages.last?.messageId ?? 0, anchor: .bottom) } } - .onChange(of: channel.allPrivateMessages, perform: { _ in + .onChange(of: channel.allPrivateMessages) { withAnimation { scrollView.scrollTo(channel.allPrivateMessages.last?.messageId ?? 0, anchor: .bottom) } - }) + } } TextMessageField( diff --git a/Meshtastic/Views/Messages/Messages.swift b/Meshtastic/Views/Messages/Messages.swift index 9785c7bf..1267d3e2 100644 --- a/Meshtastic/Views/Messages/Messages.swift +++ b/Meshtastic/Views/Messages/Messages.swift @@ -87,7 +87,7 @@ struct Messages: View { } else if case .directMessages = router.navigationState.messages { Text("Select a conversation") } - }.onChange(of: router.navigationState) { _ in + }.onChange(of: router.navigationState) { setupNavigationState() } } diff --git a/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift b/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift index 7aded0f1..1eca5015 100644 --- a/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift +++ b/Meshtastic/Views/Messages/TextMessageField/TextMessageField.swift @@ -30,14 +30,14 @@ struct TextMessageField: View { HStack(alignment: .top) { ZStack { TextField("message", text: $typingMessage, axis: .vertical) - .onChange(of: typingMessage, perform: { value in + .onChange(of: typingMessage) { _, value in totalBytes = value.utf8.count // Only mess with the value if it is too big while totalBytes > Self.maxbytes { typingMessage = String(typingMessage.dropLast()) totalBytes = typingMessage.utf8.count } - }) + } .keyboardType(.default) .toolbar { ToolbarItemGroup(placement: .keyboard) { diff --git a/Meshtastic/Views/Messages/UserList.swift b/Meshtastic/Views/Messages/UserList.swift index 9d25b590..4a4028e2 100644 --- a/Meshtastic/Views/Messages/UserList.swift +++ b/Meshtastic/Views/Messages/UserList.swift @@ -199,12 +199,12 @@ struct UserList: View { .sheet(isPresented: $showingHelp) { DirectMessagesHelp() } - .onChange(of: searchText) { _ in + .onChange(of: searchText) { Task { await searchUserList() } } - .onChange(of: viaLora) { _ in + .onChange(of: viaLora) { if !viaLora && !viaMqtt { viaMqtt = true } @@ -212,7 +212,7 @@ struct UserList: View { await searchUserList() } } - .onChange(of: viaMqtt) { _ in + .onChange(of: viaMqtt) { if !viaLora && !viaMqtt { viaLora = true } @@ -220,27 +220,27 @@ struct UserList: View { await searchUserList() } } - .onChange(of: [deviceRoles]) { _ in + .onChange(of: [deviceRoles]) { Task { await searchUserList() } } - .onChange(of: hopsAway) { _ in + .onChange(of: hopsAway) { Task { await searchUserList() } } - .onChange(of: [boolFilters]) { _ in + .onChange(of: [boolFilters]) { Task { await searchUserList() } } - .onChange(of: maxDistance) { _ in + .onChange(of: maxDistance) { Task { await searchUserList() } } - .onChange(of: isPkiEncrypted) { _ in + .onChange(of: isPkiEncrypted) { Task { await searchUserList() } diff --git a/Meshtastic/Views/Messages/UserMessageList.swift b/Meshtastic/Views/Messages/UserMessageList.swift index cb483745..7ce190fc 100644 --- a/Meshtastic/Views/Messages/UserMessageList.swift +++ b/Meshtastic/Views/Messages/UserMessageList.swift @@ -122,11 +122,11 @@ struct UserMessageList: View { scrollView.scrollTo(user.messageList.last?.messageId ?? 0, anchor: .bottom) } } - .onChange(of: user.messageList, perform: { _ in + .onChange(of: user.messageList) { withAnimation { scrollView.scrollTo(user.messageList.last?.messageId ?? 0, anchor: .bottom) } - }) + } } TextMessageField( diff --git a/Meshtastic/Views/Nodes/DeviceMetricsLog.swift b/Meshtastic/Views/Nodes/DeviceMetricsLog.swift index 9f30efc4..0239e476 100644 --- a/Meshtastic/Views/Nodes/DeviceMetricsLog.swift +++ b/Meshtastic/Views/Nodes/DeviceMetricsLog.swift @@ -207,7 +207,7 @@ struct DeviceMetricsLog: View { .padding(.bottom) .padding(.trailing) } - .onChange(of: selection) { newSelection in + .onChange(of: selection) { _, newSelection in guard let metrics = deviceMetrics.first(where: { $0.id == newSelection }) else { return } diff --git a/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift b/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift index fed672d0..088787b9 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/MapSettingsForm.swift @@ -36,7 +36,7 @@ struct MapSettingsForm: View { .pickerStyle(SegmentedPickerStyle()) .padding(.top, 5) .padding(.bottom, 5) - .onChange(of: mapLayer) { newMapLayer in + .onChange(of: mapLayer) { _, newMapLayer in UserDefaults.mapLayer = newMapLayer } if meshMap { @@ -50,7 +50,7 @@ struct MapSettingsForm: View { } .pickerStyle(DefaultPickerStyle()) } - .onChange(of: meshMapDistance) { newMeshMapDistance in + .onChange(of: meshMapDistance) { _, newMeshMapDistance in UserDefaults.meshMapDistance = newMeshMapDistance } Toggle(isOn: $waypoints) { diff --git a/Meshtastic/Views/Nodes/Helpers/Map/NodeMapSwiftUI.swift b/Meshtastic/Views/Nodes/Helpers/Map/NodeMapSwiftUI.swift index 5b264867..1120e811 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/NodeMapSwiftUI.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/NodeMapSwiftUI.swift @@ -80,7 +80,7 @@ struct NodeMapSwiftUI: View { } .sheet(isPresented: $isEditingSettings) { MapSettingsForm(traffic: $showTraffic, pointsOfInterest: $showPointsOfInterest, mapLayer: $selectedMapLayer, meshMap: $isMeshMap) - .onChange(of: (selectedMapLayer)) { newMapLayer in + .onChange(of: (selectedMapLayer)) { _, newMapLayer in switch selectedMapLayer { case .standard: UserDefaults.mapLayer = newMapLayer diff --git a/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift b/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift index 88f61d76..fb019e0b 100644 --- a/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift +++ b/Meshtastic/Views/Nodes/Helpers/Map/PositionPopover.swift @@ -95,7 +95,6 @@ struct PositionPopover: View { } /// Altitude Label { - let formatter = MeasurementFormatter() let distanceInMeters = Measurement(value: Double(position.altitude), unit: UnitLength.meters) let distanceInFeet = distanceInMeters.converted(to: UnitLength.feet) if Locale.current.measurementSystem == .metric { diff --git a/Meshtastic/Views/Nodes/NodeList.swift b/Meshtastic/Views/Nodes/NodeList.swift index 65f194cf..756f1179 100644 --- a/Meshtastic/Views/Nodes/NodeList.swift +++ b/Meshtastic/Views/Nodes/NodeList.swift @@ -280,12 +280,12 @@ struct NodeList: View { ContentUnavailableView("", systemImage: "line.3.horizontal") } .navigationSplitViewStyle(.balanced) - .onChange(of: searchText) { _ in + .onChange(of: searchText) { Task { await searchNodeList() } } - .onChange(of: viaLora) { _ in + .onChange(of: viaLora) { if !viaLora && !viaMqtt { viaMqtt = true } @@ -293,7 +293,7 @@ struct NodeList: View { await searchNodeList() } } - .onChange(of: viaMqtt) { _ in + .onChange(of: viaMqtt) { if !viaLora && !viaMqtt { viaLora = true } @@ -301,32 +301,32 @@ struct NodeList: View { await searchNodeList() } } - .onChange(of: [boolFilters]) { _ in + .onChange(of: [boolFilters]) { Task { await searchNodeList() } } - .onChange(of: [deviceRoles]) { _ in + .onChange(of: [deviceRoles]) { Task { await searchNodeList() } } - .onChange(of: hopsAway) { _ in + .onChange(of: hopsAway) { Task { await searchNodeList() } } - .onChange(of: maxDistance) { _ in + .onChange(of: maxDistance) { Task { await searchNodeList() } } - .onChange(of: distanceFilter) { _ in + .onChange(of: distanceFilter) { Task { await searchNodeList() } } - .onChange(of: router.navigationState) { _ in + .onChange(of: router.navigationState) { if let selected = router.navigationState.nodeListSelectedNodeNum { self.selectedNode = getNodeInfo(id: selected, context: context) } else { diff --git a/Meshtastic/Views/Settings/AppData.swift b/Meshtastic/Views/Settings/AppData.swift index 049c73cf..3f1ebf0e 100644 --- a/Meshtastic/Views/Settings/AppData.swift +++ b/Meshtastic/Views/Settings/AppData.swift @@ -67,8 +67,6 @@ struct AppData: View { let container = NSPersistentContainer(name: "Meshtastic") do { try container.restorePersistentStore(from: file.absoluteURL) - let request = MyInfoEntity.fetchRequest() - try context.fetch(request) UserDefaults.preferredPeripheralId = "" UserDefaults.preferredPeripheralNum = Int(file.pathComponents[(idiom == .phone || idiom == .pad) ? 9 : 10]) ?? 0 Logger.data.notice("🗂️ Restored a core data backup to backup/\(UserDefaults.preferredPeripheralNum, privacy: .public)") diff --git a/Meshtastic/Views/Settings/AppLog.swift b/Meshtastic/Views/Settings/AppLog.swift index e1b2e15c..b96ed806 100644 --- a/Meshtastic/Views/Settings/AppLog.swift +++ b/Meshtastic/Views/Settings/AppLog.swift @@ -131,25 +131,25 @@ struct AppLog: View { logs.sort(using: sortOrder) } } - .onChange(of: searchText) { _ in + .onChange(of: searchText) { Task { await logs = searchAppLogs() logs.sort(using: sortOrder) } } - .onChange(of: [categories]) { _ in + .onChange(of: [categories]) { Task { await logs = searchAppLogs() logs.sort(using: sortOrder) } } - .onChange(of: [levels]) { _ in + .onChange(of: [levels]) { Task { await logs = searchAppLogs() logs.sort(using: sortOrder) } } - .onChange(of: selection) { newSelection in + .onChange(of: selection) { _, newSelection in presentingErrorDetails = true let log = logs.first { $0.id == newSelection diff --git a/Meshtastic/Views/Settings/Channels/ChannelForm.swift b/Meshtastic/Views/Settings/Channels/ChannelForm.swift index 05e8fd27..72d6f58b 100644 --- a/Meshtastic/Views/Settings/Channels/ChannelForm.swift +++ b/Meshtastic/Views/Settings/Channels/ChannelForm.swift @@ -39,7 +39,7 @@ struct ChannelForm: View { .disableAutocorrection(true) .keyboardType(.alphabet) .foregroundColor(Color.gray) - .onChange(of: channelName, perform: { _ in + .onChange(of: channelName) { channelName = channelName.replacing(" ", with: "") var totalBytes = channelName.utf8.count // Only mess with the value if it is too big @@ -48,7 +48,7 @@ struct ChannelForm: View { totalBytes = channelName.utf8.count } hasChanges = true - }) + } } HStack { Picker("Key Size", selection: $channelKeySize) { @@ -97,7 +97,7 @@ struct ChannelForm: View { , lineWidth: 2.0) ) - .onChange(of: channelKey, perform: { _ in + .onChange(of: channelKey) { let tempKey = Data(base64Encoded: channelKey) ?? Data() if tempKey.count == channelKeySize || channelKeySize == -1 { @@ -106,7 +106,7 @@ struct ChannelForm: View { hasValidKey = false } hasChanges = true - }) + } .disabled(channelKeySize <= 0) } HStack { @@ -146,7 +146,7 @@ struct ChannelForm: View { .toggleStyle(SwitchToggleStyle(tint: .accentColor)) .disabled(!supportedVersion) .listRowSeparator(.visible) - .onChange(of: preciseLocation) { pl in + .onChange(of: preciseLocation) { _, pl in if pl == false { positionPrecision = 14 } @@ -184,10 +184,10 @@ struct ChannelForm: View { .listRowSeparator(.visible) } } - .onChange(of: channelName) { _ in + .onChange(of: channelName) { hasChanges = true } - .onChange(of: channelKeySize) { _ in + .onChange(of: channelKeySize) { if channelKeySize == -1 { channelKey = "AQ==" } else { @@ -196,10 +196,10 @@ struct ChannelForm: View { } hasChanges = true } - .onChange(of: channelKey) { _ in + .onChange(of: channelKey) { hasChanges = true } - .onChange(of: channelKeySize) { _ in + .onChange(of: channelKeySize) { if channelKeySize == -1 { if channelRole == 0 { preciseLocation = false @@ -207,10 +207,10 @@ struct ChannelForm: View { channelKey = "AQ==" } } - .onChange(of: channelRole) { _ in + .onChange(of: channelRole) { hasChanges = true } - .onChange(of: preciseLocation) { loc in + .onChange(of: preciseLocation) { _, loc in if loc == true { if channelKey == "AQ==" { preciseLocation = false @@ -223,10 +223,10 @@ struct ChannelForm: View { } hasChanges = true } - .onChange(of: positionPrecision) { _ in + .onChange(of: positionPrecision) { hasChanges = true } - .onChange(of: positionsEnabled) { pe in + .onChange(of: positionsEnabled) { _, pe in if pe { if positionPrecision == 0 { positionPrecision = 14 @@ -236,10 +236,10 @@ struct ChannelForm: View { } hasChanges = true } - .onChange(of: uplink) { _ in + .onChange(of: uplink) { hasChanges = true } - .onChange(of: downlink) { _ in + .onChange(of: downlink) { hasChanges = true } .onFirstAppear { diff --git a/Meshtastic/Views/Settings/Config/BluetoothConfig.swift b/Meshtastic/Views/Settings/Config/BluetoothConfig.swift index 46211dac..bf036aca 100644 --- a/Meshtastic/Views/Settings/Config/BluetoothConfig.swift +++ b/Meshtastic/Views/Settings/Config/BluetoothConfig.swift @@ -45,7 +45,7 @@ struct BluetoothConfig: View { Label("bluetooth.mode.fixedpin", systemImage: "wallet.pass") TextField("bluetooth.mode.fixedpin", text: $fixedPin) .foregroundColor(.gray) - .onChange(of: fixedPin, perform: { _ in + .onChange(of: fixedPin) { // Don't let the first character be 0 because it will get stripped when saving a UInt32 if fixedPin.first == "0" { fixedPin = fixedPin.replacing("0", with: "") @@ -59,7 +59,7 @@ struct BluetoothConfig: View { } else if fixedPin.utf8.count < pinLength { shortPin = true } - }) + } .foregroundColor(.gray) } .keyboardType(.decimalPad) diff --git a/Meshtastic/Views/Settings/Config/DeviceConfig.swift b/Meshtastic/Views/Settings/Config/DeviceConfig.swift index 117c0683..9d20782c 100644 --- a/Meshtastic/Views/Settings/Config/DeviceConfig.swift +++ b/Meshtastic/Views/Settings/Config/DeviceConfig.swift @@ -95,7 +95,7 @@ struct DeviceConfig: View { Label("Time Zone", systemImage: "clock.badge.exclamationmark") TextField("Time Zone", text: $tzdef, axis: .vertical) .foregroundColor(.gray) - .onChange(of: tzdef) { _ in + .onChange(of: tzdef) { var totalBytes = tzdef.utf8.count // Only mess with the value if it is too big while totalBytes > 63 { diff --git a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift index 568be9da..dff48797 100644 --- a/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/CannedMessagesConfig.swift @@ -71,8 +71,7 @@ struct CannedMessagesConfig: View { .foregroundColor(.gray) .autocapitalization(.none) .disableAutocorrection(true) - .onChange(of: messages, perform: { _ in - + .onChange(of: messages) { var totalBytes = messages.utf8.count // Only mess with the value if it is too big while totalBytes > 198 { @@ -80,7 +79,7 @@ struct CannedMessagesConfig: View { totalBytes = messages.utf8.count } hasMessagesChanges = true - }) + } .foregroundColor(.gray) } .keyboardType(.default) diff --git a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift index c077c92e..67bbc248 100644 --- a/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/MQTTConfig.swift @@ -123,14 +123,14 @@ struct MQTTConfig: View { Label("Root Topic", systemImage: "tree") TextField("Root Topic", text: $root) .foregroundColor(.gray) - .onChange(of: root, perform: { _ in + .onChange(of: root) { var totalBytes = root.utf8.count // Only mess with the value if it is too big while totalBytes > 30 { root = String(root.dropLast()) totalBytes = root.utf8.count } - }) + } .foregroundColor(.gray) } .keyboardType(.asciiCapable) @@ -162,7 +162,7 @@ struct MQTTConfig: View { .foregroundColor(.gray) .autocapitalization(.none) .disableAutocorrection(true) - .onChange(of: address, perform: { _ in + .onChange(of: address) { var totalBytes = address.utf8.count // Only mess with the value if it is too big while totalBytes > 62 { @@ -170,7 +170,7 @@ struct MQTTConfig: View { totalBytes = address.utf8.count } hasChanges = true - }) + } .keyboardType(.default) } .autocorrectionDisabled() @@ -181,7 +181,7 @@ struct MQTTConfig: View { .foregroundColor(.gray) .autocapitalization(.none) .disableAutocorrection(true) - .onChange(of: username, perform: { _ in + .onChange(of: username) { var totalBytes = username.utf8.count // Only mess with the value if it is too big while totalBytes > 62 { @@ -189,7 +189,7 @@ struct MQTTConfig: View { totalBytes = username.utf8.count } hasChanges = true - }) + } .foregroundColor(.gray) } .keyboardType(.default) @@ -200,7 +200,7 @@ struct MQTTConfig: View { .foregroundColor(.gray) .autocapitalization(.none) .disableAutocorrection(true) - .onChange(of: password, perform: { _ in + .onChange(of: password) { var totalBytes = password.utf8.count // Only mess with the value if it is too big while totalBytes > 62 { @@ -208,7 +208,7 @@ struct MQTTConfig: View { totalBytes = password.utf8.count } hasChanges = true - }) + } .foregroundColor(.gray) } .keyboardType(.default) diff --git a/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift b/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift index 1141bc7d..2fd97646 100644 --- a/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/PaxCounterConfig.swift @@ -79,11 +79,11 @@ struct PaxCounterConfig: View { } } } - .onChange(of: enabled) { - if $0 != node?.paxCounterConfig?.enabled { hasChanges = true } + .onChange(of: enabled) { oldEnabled, newEnabled in + if oldEnabled != newEnabled && newEnabled != node?.paxCounterConfig?.enabled { hasChanges = true } } - .onChange(of: paxcounterUpdateInterval) { - if $0 != node?.paxCounterConfig?.updateInterval ?? -1 { hasChanges = true } + .onChange(of: paxcounterUpdateInterval) { oldPaxcounterUpdateInterval, newPaxcounterUpdateInterval in + if oldPaxcounterUpdateInterval != newPaxcounterUpdateInterval && newPaxcounterUpdateInterval != node?.paxCounterConfig?.updateInterval ?? -1 { hasChanges = true } } SaveConfigButton(node: node, hasChanges: $hasChanges) { diff --git a/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift b/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift index aeee9601..a1217bcf 100644 --- a/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift +++ b/Meshtastic/Views/Settings/Config/Module/StoreForwardConfig.swift @@ -167,32 +167,26 @@ struct StoreForwardConfig: View { } } } - .onChange(of: enabled) { newEnabled in - if node != nil && node?.storeForwardConfig != nil { - if newEnabled != node!.storeForwardConfig!.enabled { hasChanges = true } - } + .onChange(of: enabled) { oldEnabled, newEnabled in + if oldEnabled != newEnabled && newEnabled != node!.storeForwardConfig!.enabled { hasChanges = true } } - .onChange(of: isRouter) { newIsRouter in - if node != nil && node?.storeForwardConfig != nil { - if newIsRouter != node!.storeForwardConfig!.isRouter { hasChanges = true } - } + .onChange(of: isRouter) { oldIsRouter, newIsRouter in + if oldIsRouter != newIsRouter && newIsRouter != node!.storeForwardConfig!.isRouter { hasChanges = true } } - .onChange(of: heartbeat) { newHeartbeat in - if node != nil && node?.storeForwardConfig != nil { - if newHeartbeat != node!.storeForwardConfig!.heartbeat { hasChanges = true } - } + .onChange(of: heartbeat) { oldHeartbeat, newHeartbeat in + if oldHeartbeat != newHeartbeat && newHeartbeat != node!.storeForwardConfig!.heartbeat { hasChanges = true } } - .onChange(of: records) { newRecords in + .onChange(of: records) { oldRecords, newRecords in if node != nil && node?.storeForwardConfig != nil { if newRecords != node!.storeForwardConfig!.records { hasChanges = true } } } - .onChange(of: historyReturnMax) { newHistoryReturnMax in + .onChange(of: historyReturnMax) { oldHistoryReturnMax, newHistoryReturnMax in if node != nil && node?.storeForwardConfig != nil { if newHistoryReturnMax != node!.storeForwardConfig!.historyReturnMax { hasChanges = true } } } - .onChange(of: historyReturnWindow) { newHistoryReturnWindow in + .onChange(of: historyReturnWindow) { oldHistoryReturnWindow, newHistoryReturnWindow in if node != nil && node?.storeForwardConfig != nil { if newHistoryReturnWindow != node!.storeForwardConfig!.historyReturnWindow { hasChanges = true } } diff --git a/Meshtastic/Views/Settings/Config/NetworkConfig.swift b/Meshtastic/Views/Settings/Config/NetworkConfig.swift index 198ad1a0..b79740e2 100644 --- a/Meshtastic/Views/Settings/Config/NetworkConfig.swift +++ b/Meshtastic/Views/Settings/Config/NetworkConfig.swift @@ -45,7 +45,7 @@ struct NetworkConfig: View { .foregroundColor(.gray) .autocapitalization(.none) .disableAutocorrection(true) - .onChange(of: wifiSsid, perform: { _ in + .onChange(of: wifiSsid) { var totalBytes = wifiSsid.utf8.count // Only mess with the value if it is too big while totalBytes > 32 { @@ -53,7 +53,7 @@ struct NetworkConfig: View { totalBytes = wifiSsid.utf8.count } hasChanges = true - }) + } .foregroundColor(.gray) } .keyboardType(.default) @@ -63,7 +63,7 @@ struct NetworkConfig: View { .foregroundColor(.gray) .autocapitalization(.none) .disableAutocorrection(true) - .onChange(of: wifiPsk, perform: { _ in + .onChange(of: wifiPsk) { var totalBytes = wifiPsk.utf8.count // Only mess with the value if it is too big while totalBytes > 63 { @@ -71,7 +71,7 @@ struct NetworkConfig: View { totalBytes = wifiPsk.utf8.count } hasChanges = true - }) + } .foregroundColor(.gray) } .keyboardType(.default) @@ -154,10 +154,10 @@ struct NetworkConfig: View { .onChange(of: wifiEnabled) { if $0 != node?.networkConfig?.wifiEnabled { hasChanges = true } } - .onChange(of: wifiSsid) { newSSID in + .onChange(of: wifiSsid) { _, newSSID in if newSSID != node?.networkConfig?.wifiSsid { hasChanges = true } } - .onChange(of: wifiPsk) { newPsk in + .onChange(of: wifiPsk) { _, newPsk in if newPsk != node?.networkConfig?.wifiPsk { hasChanges = true } } .onChange(of: wifiMode) { diff --git a/Meshtastic/Views/Settings/Config/PositionConfig.swift b/Meshtastic/Views/Settings/Config/PositionConfig.swift index 4497c1f7..541146cc 100644 --- a/Meshtastic/Views/Settings/Config/PositionConfig.swift +++ b/Meshtastic/Views/Settings/Config/PositionConfig.swift @@ -398,7 +398,7 @@ struct PositionConfig: View { } } } - .onChange(of: fixedPosition) { newFixed in + .onChange(of: fixedPosition) { _, newFixed in if supportedVersion { if let positionConfig = node?.positionConfig { /// Fixed Position is off to start diff --git a/Meshtastic/Views/Settings/Config/PowerConfig.swift b/Meshtastic/Views/Settings/Config/PowerConfig.swift index 9ba0fe0a..83454820 100644 --- a/Meshtastic/Views/Settings/Config/PowerConfig.swift +++ b/Meshtastic/Views/Settings/Config/PowerConfig.swift @@ -232,13 +232,13 @@ private struct FloatField: View { TextField(title.localized, value: $typingNumber, format: .number) .foregroundColor(.gray) .multilineTextAlignment(.trailing) - .onChange(of: typingNumber, perform: { _ in + .onChange(of: typingNumber) { if isValid(typingNumber) { number = typingNumber } else { typingNumber = number } - }) + } .keyboardType(.decimalPad) .onAppear { typingNumber = number diff --git a/Meshtastic/Views/Settings/Config/SecurityConfig.swift b/Meshtastic/Views/Settings/Config/SecurityConfig.swift index 95a07dfb..c7abe54b 100644 --- a/Meshtastic/Views/Settings/Config/SecurityConfig.swift +++ b/Meshtastic/Views/Settings/Config/SecurityConfig.swift @@ -118,7 +118,7 @@ struct SecurityConfig: View { .onChange(of: adminChannelEnabled) { if $0 != node?.securityConfig?.adminChannelEnabled { hasChanges = true } } - .onChange(of: publicKey) { _ in + .onChange(of: publicKey) { let tempKey = Data(base64Encoded: publicKey) ?? Data() if tempKey.count == 32 { hasValidPublicKey = true @@ -127,7 +127,7 @@ struct SecurityConfig: View { } hasChanges = true } - .onChange(of: privateKey) { _ in + .onChange(of: privateKey) { let tempKey = Data(base64Encoded: privateKey) ?? Data() if tempKey.count == 32 { hasValidPrivateKey = true @@ -136,7 +136,7 @@ struct SecurityConfig: View { } hasChanges = true } - .onChange(of: adminKey) { key in + .onChange(of: adminKey) { _, key in let tempKey = Data(base64Encoded: key) ?? Data() if key.isEmpty { hasValidAdminKey = true diff --git a/Meshtastic/Views/Settings/RouteRecorder.swift b/Meshtastic/Views/Settings/RouteRecorder.swift index ea2cdc41..82e7bb32 100644 --- a/Meshtastic/Views/Settings/RouteRecorder.swift +++ b/Meshtastic/Views/Settings/RouteRecorder.swift @@ -283,7 +283,7 @@ struct RouteRecorder: View { .onDisappear(perform: { UIApplication.shared.isIdleTimerDisabled = false }) - .onChange(of: locationsHandler.locationsArray.last) { newLoc in + .onChange(of: locationsHandler.locationsArray.last) { _, newLoc in if locationsHandler.isRecording { if let loc = newLoc { if recording != nil { diff --git a/Meshtastic/Views/Settings/Routes.swift b/Meshtastic/Views/Settings/Routes.swift index 625c2a56..174221d2 100644 --- a/Meshtastic/Views/Settings/Routes.swift +++ b/Meshtastic/Views/Settings/Routes.swift @@ -57,7 +57,6 @@ struct Routes: View { } do { - guard let fileContent = String(data: try Data(contentsOf: selectedFile), encoding: .utf8) else { return } let routeName = selectedFile.lastPathComponent.dropLast(4) let lines = fileContent.components(separatedBy: "\n") @@ -175,14 +174,14 @@ struct Routes: View { axis: .vertical ) .foregroundColor(Color.gray) - .onChange(of: name, perform: { _ in + .onChange(of: name) { var totalBytes = name.utf8.count // Only mess with the value if it is too big while totalBytes > 100 { name = String(name.dropLast()) totalBytes = name.utf8.count } - }) + } Toggle(isOn: $enabled) { Label("enabled", systemImage: "point.topleft.filled.down.to.point.bottomright.curvepath") @@ -236,16 +235,16 @@ struct Routes: View { .controlSize(.large) .disabled(!hasChanges) } - .onChange(of: name) { _ in + .onChange(of: name) { hasChanges = true } - .onChange(of: notes) { _ in + .onChange(of: notes) { hasChanges = true } - .onChange(of: enabled) { _ in + .onChange(of: enabled) { hasChanges = true } - .onChange(of: color) { _ in + .onChange(of: color) { hasChanges = true } Map { diff --git a/Meshtastic/Views/Settings/Settings.swift b/Meshtastic/Views/Settings/Settings.swift index 52a78b0a..ab8c97b3 100644 --- a/Meshtastic/Views/Settings/Settings.swift +++ b/Meshtastic/Views/Settings/Settings.swift @@ -161,7 +161,7 @@ struct Settings: View { Image(systemName: "light.max") } } - + NavigationLink(value: SettingsNavigationState.cannedMessages) { Label { Text("canned.messages") @@ -335,7 +335,6 @@ struct Settings: View { .foregroundColor(.red) } } - if !(node?.deviceConfig?.isManaged ?? false) { if bleManager.connectedPeripheral != nil { @@ -387,7 +386,7 @@ struct Settings: View { } } .pickerStyle(.navigationLink) - .onChange(of: selectedNode) { newValue in + .onChange(of: selectedNode) { _, newValue in if selectedNode > 0 { let node = nodes.first(where: { $0.num == newValue }) let connectedNode = nodes.first(where: { $0.num == preferredNodeNum }) @@ -483,7 +482,7 @@ struct Settings: View { Firmware(node: node) } } - .onChange(of: UserDefaults.preferredPeripheralNum ) { newConnectedNode in + .onChange(of: UserDefaults.preferredPeripheralNum ) { _, newConnectedNode in preferredNodeNum = newConnectedNode if nodes.count > 1 { if selectedNode == 0 { diff --git a/Meshtastic/Views/Settings/ShareChannels.swift b/Meshtastic/Views/Settings/ShareChannels.swift index e4b293a8..1e10c571 100644 --- a/Meshtastic/Views/Settings/ShareChannels.swift +++ b/Meshtastic/Views/Settings/ShareChannels.swift @@ -235,15 +235,15 @@ struct ShareChannels: View { .onAppear { generateChannelSet() } - .onChange(of: includeChannel0) { _ in generateChannelSet() } - .onChange(of: includeChannel1) { _ in generateChannelSet() } - .onChange(of: includeChannel2) { _ in generateChannelSet() } - .onChange(of: includeChannel3) { _ in generateChannelSet() } - .onChange(of: includeChannel4) { _ in generateChannelSet() } - .onChange(of: includeChannel5) { _ in generateChannelSet() } - .onChange(of: includeChannel6) { _ in generateChannelSet() } - .onChange(of: includeChannel7) { _ in generateChannelSet() } - .onChange(of: replaceChannels) { _ in generateChannelSet() } + .onChange(of: includeChannel0) { generateChannelSet() } + .onChange(of: includeChannel1) { generateChannelSet() } + .onChange(of: includeChannel2) { generateChannelSet() } + .onChange(of: includeChannel3) { generateChannelSet() } + .onChange(of: includeChannel4) { generateChannelSet() } + .onChange(of: includeChannel5) { generateChannelSet() } + .onChange(of: includeChannel6) { generateChannelSet() } + .onChange(of: includeChannel7) { generateChannelSet() } + .onChange(of: replaceChannels) { generateChannelSet() } } } func generateChannelSet() { diff --git a/Meshtastic/Views/Settings/UserConfig.swift b/Meshtastic/Views/Settings/UserConfig.swift index 72084954..daacb849 100644 --- a/Meshtastic/Views/Settings/UserConfig.swift +++ b/Meshtastic/Views/Settings/UserConfig.swift @@ -49,14 +49,14 @@ struct UserConfig: View { Label(isLicensed ? "Call Sign" : "Long Name", systemImage: "person.crop.rectangle.fill") TextField("Long Name", text: $longName) - .onChange(of: longName, perform: { _ in + .onChange(of: longName) { var totalBytes = longName.utf8.count // Only mess with the value if it is too big while totalBytes > (isLicensed ? 6 : 36) { longName = String(longName.dropLast()) totalBytes = longName.utf8.count } - }) + } } .keyboardType(.default) .disableAutocorrection(true) @@ -74,14 +74,14 @@ struct UserConfig: View { Label("Short Name", systemImage: "circlebadge.fill") TextField("Short Name", text: $shortName) .foregroundColor(.gray) - .onChange(of: shortName, perform: { _ in + .onChange(of: shortName) { var totalBytes = shortName.utf8.count // Only mess with the value if it is too big if totalBytes > 4 { shortName = String(shortName.dropLast()) totalBytes = shortName.utf8.count } - }) + } .foregroundColor(.gray) } .keyboardType(.default) @@ -197,17 +197,17 @@ struct UserConfig: View { self.overrideFrequency = node?.loRaConfig?.overrideFrequency ?? 0.00 self.hasChanges = false } - .onChange(of: shortName) { newShort in + .onChange(of: shortName) { _, newShort in if node != nil && node!.user != nil { if newShort != node?.user!.shortName { hasChanges = true } } } - .onChange(of: longName) { newLong in + .onChange(of: longName) { _, newLong in if node != nil && node!.user != nil { if newLong != node?.user!.longName { hasChanges = true } } } - .onChange(of: isLicensed) { newIsLicensed in + .onChange(of: isLicensed) { _, newIsLicensed in if node != nil && node!.user != nil { if newIsLicensed != node?.user!.isLicensed { hasChanges = true @@ -219,10 +219,10 @@ struct UserConfig: View { } } } - .onChange(of: overrideFrequency) { _ in + .onChange(of: overrideFrequency) { hasChanges = true } - .onChange(of: txPower) { _ in + .onChange(of: txPower) { hasChanges = true } } diff --git a/Widgets/WidgetsLiveActivity.swift b/Widgets/WidgetsLiveActivity.swift index 06099bd1..e16e3913 100644 --- a/Widgets/WidgetsLiveActivity.swift +++ b/Widgets/WidgetsLiveActivity.swift @@ -120,7 +120,6 @@ struct WidgetsLiveActivity: Widget { } } - struct WidgetsLiveActivity_Previews: PreviewProvider { static let attributes = MeshActivityAttributes(nodeNum: 123456789, name: "RAK Compact Rotary Handset Gray 8E6G") static let state = MeshActivityAttributes.ContentState(uptimeSeconds: 600, channelUtilization: 1.2, airtime: 3.5, sentPackets: 12587, receivedPackets: 12555, badReceivedPackets: 800, nodesOnline: 99, totalNodes: 100, timerRange: Date.now...Date(timeIntervalSinceNow: 300))