From df1fbef9afafd05529835c8b4758c70e7d66475e Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Wed, 16 Feb 2022 07:37:08 -0800 Subject: [PATCH 1/3] Add channel utilization and airtime, set up core data migration to remove unnecessary fields --- Meshtastic Client.xcodeproj/project.pbxproj | 8 +- MeshtasticClient/Helpers/BLEManager.swift | 16 ++-- MeshtasticClient/Info.plist | 4 +- .../Meshtastic.xcdatamodeld/.xccurrentversion | 2 +- .../CoreDataSample.xcdatamodel/contents | 11 +-- .../contents | 85 +++++++++++++++++++ MeshtasticClient/Model/PeripheralModel.swift | 6 +- .../Views/Bluetooth/Connect.swift | 5 +- .../Views/Helpers/CircleText.swift | 2 +- .../Views/Messages/Contacts.swift | 2 - 10 files changed, 118 insertions(+), 23 deletions(-) create mode 100644 MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v2.xcdatamodel/contents diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index 77d3423d..1d8fcf89 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -85,6 +85,7 @@ DD1BF2F82776FE2E008C8D2F /* UserMessageList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserMessageList.swift; sourceTree = ""; }; DD23A50E26FD1B4400D9B90C /* PeripheralModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeripheralModel.swift; sourceTree = ""; }; DD2E65252767A01F00E45FC5 /* NodeDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeDetail.swift; sourceTree = ""; }; + DD45C77427BD4EF80011784F /* MeshtasticDataModel v2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MeshtasticDataModel v2.xcdatamodel"; sourceTree = ""; }; DD47E3CD26F103C600029299 /* NodeList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeList.swift; sourceTree = ""; }; DD47E3D526F17ED900029299 /* CircleText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleText.swift; sourceTree = ""; }; DD47E3D826F3093800029299 /* MessageBubble.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageBubble.swift; sourceTree = ""; }; @@ -754,7 +755,7 @@ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,6"; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; @@ -784,7 +785,7 @@ SUPPORTS_MACCATALYST = YES; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,6"; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; @@ -949,9 +950,10 @@ DD9D8F2D2764403B00080993 /* Meshtastic.xcdatamodeld */ = { isa = XCVersionGroup; children = ( + DD45C77427BD4EF80011784F /* MeshtasticDataModel v2.xcdatamodel */, DD9D8F2E2764403B00080993 /* CoreDataSample.xcdatamodel */, ); - currentVersion = DD9D8F2E2764403B00080993 /* CoreDataSample.xcdatamodel */; + currentVersion = DD45C77427BD4EF80011784F /* MeshtasticDataModel v2.xcdatamodel */; name = Meshtastic.xcdatamodeld; path = MeshtasticClient/Meshtastic.xcdatamodeld; sourceTree = ""; diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index 77500b03..bd6d9ae4 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -173,7 +173,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph peripheralName = name } - let newPeripheral = Peripheral(id: peripheral.identifier.uuidString, num: 0, name: peripheralName, shortName: String(peripheralName.suffix(3)), longName: peripheralName, firmwareVersion: "Unknown", rssi: RSSI.intValue, subscribed: false, peripheral: peripheral) + let newPeripheral = Peripheral(id: peripheral.identifier.uuidString, num: 0, name: peripheralName, shortName: String(peripheralName.suffix(3)), longName: peripheralName, firmwareVersion: "Unknown", rssi: RSSI.intValue, channelUtilization: nil, airTime: nil, subscribed: false, peripheral: peripheral) let peripheralIndex = peripherals.firstIndex(where: { $0.id == newPeripheral.id }) if peripheralIndex != nil && newPeripheral.peripheral.state != CBPeripheralState.connected { @@ -409,7 +409,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph myInfo.myNodeNum = Int64(decodedInfo.myInfo.myNodeNum) myInfo.hasGps = decodedInfo.myInfo.hasGps_p myInfo.channelUtilization = decodedInfo.myInfo.channelUtilization - myInfo.numBands = Int32(bitPattern: decodedInfo.myInfo.numBands) // Swift does strings weird, this does work let lastDotIndex = decodedInfo.myInfo.firmwareVersion.lastIndex(of: ".")//.lastIndex(of: ".", offsetBy: -1) @@ -424,6 +423,8 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph self.connectedPeripheral.num = myInfo.myNodeNum self.connectedPeripheral.firmwareVersion = myInfo.firmwareVersion ?? "Unknown" self.connectedPeripheral.name = myInfo.bleName ?? "Unknown" + self.connectedPeripheral.channelUtilization = myInfo.channelUtilization + self.connectedPeripheral.airTime = myInfo.airUtilTx let fetchBCUserRequest: NSFetchRequest = NSFetchRequest.init(entityName: "UserEntity") fetchBCUserRequest.predicate = NSPredicate(format: "num == %lld", Int64(decodedInfo.myInfo.myNodeNum)) @@ -452,7 +453,6 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph fetchedMyInfo[0].myNodeNum = Int64(decodedInfo.myInfo.myNodeNum) fetchedMyInfo[0].hasGps = decodedInfo.myInfo.hasGps_p fetchedMyInfo[0].channelUtilization = decodedInfo.myInfo.channelUtilization - fetchedMyInfo[0].numBands = Int32(bitPattern: decodedInfo.myInfo.numBands) let lastDotIndex = decodedInfo.myInfo.firmwareVersion.lastIndex(of: ".")//.lastIndex(of: ".", offsetBy: -1) var version = decodedInfo.myInfo.firmwareVersion[...(lastDotIndex ?? String.Index(utf16Offset:6, in: decodedInfo.myInfo.firmwareVersion))] version = version.dropLast() @@ -461,9 +461,11 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph fetchedMyInfo[0].messageTimeoutMsec = Int32(bitPattern: decodedInfo.myInfo.messageTimeoutMsec) fetchedMyInfo[0].minAppVersion = Int32(bitPattern: decodedInfo.myInfo.minAppVersion) fetchedMyInfo[0].maxChannels = Int32(bitPattern: decodedInfo.myInfo.maxChannels) - connectedPeripheral.num = fetchedMyInfo[0].myNodeNum - connectedPeripheral.firmwareVersion = fetchedMyInfo[0].firmwareVersion ?? "Unknown" - connectedPeripheral.name = fetchedMyInfo[0].bleName ?? "Unknown" + self.connectedPeripheral.num = fetchedMyInfo[0].myNodeNum + self.connectedPeripheral.firmwareVersion = fetchedMyInfo[0].firmwareVersion ?? "Unknown" + self.connectedPeripheral.name = fetchedMyInfo[0].bleName ?? "Unknown" + self.connectedPeripheral.channelUtilization = fetchedMyInfo[0].channelUtilization + self.connectedPeripheral.airTime = fetchedMyInfo[0].airUtilTx } do { @@ -781,7 +783,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph try context!.save() - if meshLoggingEnabled { MeshLogger.log("💾 Updated NodeInfo SNR and Time from Node Info App Packet For: \(Int64(decodedInfo.nodeInfo.num))")} + if meshLoggingEnabled { MeshLogger.log("💾 Updated NodeInfo SNR and Time from Node Info App Packet For: \(fetchedNode[0].num)")} print("💾 Updated NodeInfo SNR and Time from Packet For: \(fetchedNode[0].num)") } catch { diff --git a/MeshtasticClient/Info.plist b/MeshtasticClient/Info.plist index 5d7d0870..154c45af 100644 --- a/MeshtasticClient/Info.plist +++ b/MeshtasticClient/Info.plist @@ -40,11 +40,11 @@ LSRequiresIPhoneOS LSSupportsOpeningDocumentsInPlace - + NSBluetoothAlwaysUsageDescription We use bluetooth to connect to nearby Meshtastic Devices NSBluetoothPeripheralUsageDescription - Bluetooth is used to connect an iPhone to a user's meshtastic device to allow text messaging and location data for the mesh network. + Bluetooth is used to connect an iPhone to a user's meshtastic device to allow text messaging and location data for the mesh network. NSLocationWhenInUseUsageDescription We use your location to center maps of the mesh Privacy – Bluetooth Always Usage Description diff --git a/MeshtasticClient/Meshtastic.xcdatamodeld/.xccurrentversion b/MeshtasticClient/Meshtastic.xcdatamodeld/.xccurrentversion index fe2c4419..b75edd3e 100644 --- a/MeshtasticClient/Meshtastic.xcdatamodeld/.xccurrentversion +++ b/MeshtasticClient/Meshtastic.xcdatamodeld/.xccurrentversion @@ -3,6 +3,6 @@ _XCCurrentVersionName - CoreDataSample.xcdatamodel + MeshtasticDataModel v2.xcdatamodel diff --git a/MeshtasticClient/Meshtastic.xcdatamodeld/CoreDataSample.xcdatamodel/contents b/MeshtasticClient/Meshtastic.xcdatamodeld/CoreDataSample.xcdatamodel/contents index 8f7d888b..2f3fcc6b 100644 --- a/MeshtasticClient/Meshtastic.xcdatamodeld/CoreDataSample.xcdatamodel/contents +++ b/MeshtasticClient/Meshtastic.xcdatamodeld/CoreDataSample.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -20,6 +20,7 @@ + @@ -37,7 +38,6 @@ - @@ -56,6 +56,7 @@ + @@ -76,9 +77,9 @@ - - - + + + \ No newline at end of file diff --git a/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v2.xcdatamodel/contents b/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v2.xcdatamodel/contents new file mode 100644 index 00000000..6de78a4d --- /dev/null +++ b/MeshtasticClient/Meshtastic.xcdatamodeld/MeshtasticDataModel v2.xcdatamodel/contents @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MeshtasticClient/Model/PeripheralModel.swift b/MeshtasticClient/Model/PeripheralModel.swift index a65ce4df..ea6a7c7a 100644 --- a/MeshtasticClient/Model/PeripheralModel.swift +++ b/MeshtasticClient/Model/PeripheralModel.swift @@ -9,10 +9,12 @@ struct Peripheral: Identifiable { var longName: String var firmwareVersion: String var rssi: Int + var channelUtilization: Float? + var airTime: Float? var subscribed: Bool var peripheral: CBPeripheral - init(id: String, num: Int64, name: String, shortName: String, longName: String, firmwareVersion: String, rssi: Int, subscribed: Bool, peripheral: CBPeripheral) { + init(id: String, num: Int64, name: String, shortName: String, longName: String, firmwareVersion: String, rssi: Int, channelUtilization: Float?, airTime: Float?, subscribed: Bool, peripheral: CBPeripheral) { self.id = id self.num = num self.name = name @@ -20,6 +22,8 @@ struct Peripheral: Identifiable { self.longName = longName self.firmwareVersion = firmwareVersion self.rssi = rssi + self.channelUtilization = channelUtilization + self.airTime = airTime self.subscribed = subscribed self.peripheral = peripheral } diff --git a/MeshtasticClient/Views/Bluetooth/Connect.swift b/MeshtasticClient/Views/Bluetooth/Connect.swift index 7bfba712..2e390b3a 100644 --- a/MeshtasticClient/Views/Bluetooth/Connect.swift +++ b/MeshtasticClient/Views/Bluetooth/Connect.swift @@ -26,7 +26,6 @@ struct Connect: View { let firmwareVersion = bleManager.lastConnnectionVersion let minimumVersion = "1.2.52" let supportedVersion = firmwareVersion == "0.0.0" || minimumVersion.compare(firmwareVersion, options: .numeric) == .orderedAscending || minimumVersion.compare(firmwareVersion, options: .numeric) == .orderedSame - NavigationView { @@ -75,6 +74,10 @@ struct Connect: View { if bleManager.connectedPeripheral != nil { Text("FW Version: ").font(.caption)+Text(bleManager.connectedPeripheral.firmwareVersion) .font(.caption).foregroundColor(Color.gray) + Text("Channel Utilization: ").font(.caption)+Text(String(bleManager.connectedPeripheral.channelUtilization ?? 0.00)) + .font(.caption).foregroundColor(Color.gray) + Text("Air Time: ").font(.caption)+Text(String(bleManager.connectedPeripheral.airTime ?? 0.00)) + .font(.caption).foregroundColor(Color.gray) } if bleManager.connectedPeripheral.subscribed { Text("Properly Subscribed").font(.caption) diff --git a/MeshtasticClient/Views/Helpers/CircleText.swift b/MeshtasticClient/Views/Helpers/CircleText.swift index 814d508b..c8b3c6ad 100644 --- a/MeshtasticClient/Views/Helpers/CircleText.swift +++ b/MeshtasticClient/Views/Helpers/CircleText.swift @@ -9,7 +9,7 @@ struct CircleText: View { var text: String var color: Color var circleSize: CGFloat? = 50 - var fontSize: CGFloat? = 24 + var fontSize: CGFloat? = 22 var body: some View { diff --git a/MeshtasticClient/Views/Messages/Contacts.swift b/MeshtasticClient/Views/Messages/Contacts.swift index 7c201f71..45131a60 100644 --- a/MeshtasticClient/Views/Messages/Contacts.swift +++ b/MeshtasticClient/Views/Messages/Contacts.swift @@ -24,8 +24,6 @@ struct Contacts: View { List(users) { (user: UserEntity) in - //let currentUserNum = self.bleManager.connectedPeripheral != nil ? self.bleManager.connectedPeripheral.num : 0 - let allMessages = user.value(forKey: "allMessages") as! [MessageEntity] NavigationLink(destination: UserMessageList(user: user)) { From 34f43963e4557b660040f716c919f8ab04f0268e Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Wed, 16 Feb 2022 08:56:02 -0800 Subject: [PATCH 2/3] Migration updates, mac location entitlement fix --- Meshtastic Client.xcodeproj/project.pbxproj | 4 ++-- MeshtasticClient/Info.plist | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index 1d8fcf89..42abd6c2 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -738,7 +738,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; @@ -769,7 +769,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; diff --git a/MeshtasticClient/Info.plist b/MeshtasticClient/Info.plist index 154c45af..1b569687 100644 --- a/MeshtasticClient/Info.plist +++ b/MeshtasticClient/Info.plist @@ -2,6 +2,8 @@ + NSLocationUsageDescription + We use your location to display it on the mesh map as well as to have GPS coordinatess to send to the connected device. CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName @@ -46,7 +48,7 @@ NSBluetoothPeripheralUsageDescription Bluetooth is used to connect an iPhone to a user's meshtastic device to allow text messaging and location data for the mesh network. NSLocationWhenInUseUsageDescription - We use your location to center maps of the mesh + We use your location to display it on the mesh map as well as to have GPS coordinatess to send to the connected device. Privacy – Bluetooth Always Usage Description We use bluetooth to connect to nearby Meshtastic Devices UIApplicationSceneManifest From a9d09d875c25fdc73e417f1c825bc2745670c515 Mon Sep 17 00:00:00 2001 From: Garth Vander Houwen Date: Thu, 17 Feb 2022 18:07:41 -0800 Subject: [PATCH 3/3] Entitlements updates for mac, data migration and ad hoc position feature in messages --- Meshtastic Client.xcodeproj/project.pbxproj | 4 +- MeshtasticClient/Helpers/BLEManager.swift | 93 +++++++++++++++++++ MeshtasticClient/Helpers/LocationHelper.swift | 10 ++ MeshtasticClient/Info.plist | 6 +- .../Views/Messages/UserMessageList.swift | 15 +++ 5 files changed, 123 insertions(+), 5 deletions(-) diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index 42abd6c2..e697d7cb 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -738,7 +738,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; @@ -769,7 +769,7 @@ CODE_SIGN_ENTITLEMENTS = MeshtasticClient/MeshtasticClient.entitlements; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2; + CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_ASSET_PATHS = "\"MeshtasticClient/Preview Content\""; DEVELOPMENT_TEAM = GCH7VS5Y9R; ENABLE_PREVIEWS = YES; diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index bd6d9ae4..fc6643e0 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -1077,4 +1077,97 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph } return success } + + // Send Message + public func sendPosition(destNum: Int64, wantResponse: Bool) -> Bool { + + var success = false + + let fromNodeNum = connectedPeripheral.num + + if fromNodeNum <= 0 { + + return false + } + + let fetchNode: NSFetchRequest = NSFetchRequest.init(entityName: "NodeInfoEntity") + fetchNode.predicate = NSPredicate(format: "num == %lld", fromNodeNum) + + do { + + let fetchedNode = try context?.fetch(fetchNode) as! [NodeInfoEntity] + + if fetchedNode.count == 1 { + var positionPacket = Position() + positionPacket.latitudeI = Int32(LocationHelper.currentLocation.latitude * 1e7) + positionPacket.longitudeI = Int32(LocationHelper.currentLocation.longitude * 1e7) + positionPacket.time = UInt32(Date().timeIntervalSince1970) + positionPacket.altitude = Int32(LocationHelper.currentAltitude) + let mostRecentPosition = fetchedNode[0].positions?.lastObject as! PositionEntity + positionPacket.batteryLevel = mostRecentPosition.batteryLevel + + var meshPacket = MeshPacket() + meshPacket.to = UInt32(broadcastNodeNum) + meshPacket.from = UInt32(connectedPeripheral.num) + meshPacket.wantAck = wantResponse + + var dataMessage = DataMessage() + dataMessage.payload = try! positionPacket.serializedData() + dataMessage.portnum = PortNum.positionApp + + meshPacket.decoded = dataMessage + + let position = PositionEntity(context: context!) + position.latitudeI = positionPacket.latitudeI + position.longitudeI = positionPacket.longitudeI + position.altitude = positionPacket.altitude + position.batteryLevel = positionPacket.batteryLevel + position.time = Date(timeIntervalSince1970: TimeInterval(Int64(positionPacket.time))) + + let mutablePositions = fetchedNode[0].positions!.mutableCopy() as! NSMutableOrderedSet + mutablePositions.add(position) + + fetchedNode[0].positions = mutablePositions.copy() as? NSOrderedSet + + var toRadio: ToRadio! + toRadio = ToRadio() + toRadio.packet = meshPacket + let binaryData: Data = try! toRadio.serializedData() + + if meshLoggingEnabled { MeshLogger.log("📍 Sent a Position Packet for node: \(fromNodeNum)") } + print("📍 Sent a Position Packet for node: \(fromNodeNum)") + + if connectedPeripheral!.peripheral.state == CBPeripheralState.connected { + connectedPeripheral.peripheral.writeValue(binaryData, for: TORADIO_characteristic, type: .withResponse) + do { + + try context!.save() + print("💾 Saved a new position for the connected node: \(fromNodeNum)") + if meshLoggingEnabled { MeshLogger.log("💾 Saved a new position for the connected node: \(fromNodeNum)") } + success = true + + } catch { + + context!.rollback() + + let nsError = error as NSError + print("🚫 Unresolved Core Data error in Send Position Function \(nsError)") + if meshLoggingEnabled { MeshLogger.log("🚫 Unresolved Core Data error in Send Position Function \(nsError)") } + success = false + } + } + + } + + } catch { + + } + + + + + + return success + } + } diff --git a/MeshtasticClient/Helpers/LocationHelper.swift b/MeshtasticClient/Helpers/LocationHelper.swift index cb06da1c..b3459ef7 100644 --- a/MeshtasticClient/Helpers/LocationHelper.swift +++ b/MeshtasticClient/Helpers/LocationHelper.swift @@ -6,6 +6,8 @@ class LocationHelper: NSObject, ObservableObject { // Mount Rainier static let DefaultLocation = CLLocationCoordinate2D(latitude: 46.879967, longitude: -121.726906) + + static let DefaultAltitude = CLLocationDistance(integerLiteral: 0) static var currentLocation: CLLocationCoordinate2D { @@ -15,6 +17,14 @@ class LocationHelper: NSObject, ObservableObject { return location.coordinate } + static var currentAltitude: CLLocationDistance { + + guard let altitude = shared.locationManager.location?.altitude else { + return DefaultAltitude + } + return altitude + } + private let locationManager = CLLocationManager() private override init() { diff --git a/MeshtasticClient/Info.plist b/MeshtasticClient/Info.plist index 1b569687..1a7b3ab5 100644 --- a/MeshtasticClient/Info.plist +++ b/MeshtasticClient/Info.plist @@ -2,8 +2,6 @@ - NSLocationUsageDescription - We use your location to display it on the mesh map as well as to have GPS coordinatess to send to the connected device. CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName @@ -46,7 +44,9 @@ NSBluetoothAlwaysUsageDescription We use bluetooth to connect to nearby Meshtastic Devices NSBluetoothPeripheralUsageDescription - Bluetooth is used to connect an iPhone to a user's meshtastic device to allow text messaging and location data for the mesh network. + Bluetooth is used to connect an iPhone to a user's meshtastic device to allow text messaging and location data for the mesh network. + NSLocationUsageDescription + We use your location to display it on the mesh map as well as to have GPS coordinatess to send to the connected device. NSLocationWhenInUseUsageDescription We use your location to display it on the mesh map as well as to have GPS coordinatess to send to the connected device. Privacy – Bluetooth Always Usage Description diff --git a/MeshtasticClient/Views/Messages/UserMessageList.swift b/MeshtasticClient/Views/Messages/UserMessageList.swift index c97fcc99..4ba8b7ee 100644 --- a/MeshtasticClient/Views/Messages/UserMessageList.swift +++ b/MeshtasticClient/Views/Messages/UserMessageList.swift @@ -28,6 +28,7 @@ struct UserMessageList: View { @State var showDeleteMessageAlert = false @State private var deleteMessageId: Int64 = 0 @State private var replyMessageId: Int64 = 0 + @State private var sendPositionWithMessage: Bool = false @State var messageCount = 0 @@ -385,6 +386,15 @@ struct UserMessageList: View { .font(.subheadline) Spacer() + + Button { + let userLongName = bleManager.connectedPeripheral != nil ? bleManager.connectedPeripheral.longName : "Unknown" + sendPositionWithMessage = true + typingMessage = "📍 " + userLongName + " Has shared their position with the mesh." + + } label: { + Image(systemName: "mappin") + } ProgressView("Bytes: \(totalBytes) / \(maxbytes)", value: Double(totalBytes), total: Double(maxbytes)) .frame(width: 130) @@ -409,6 +419,11 @@ struct UserMessageList: View { typingMessage = "" focusedField = nil replyMessageId = 0 + if sendPositionWithMessage { + if bleManager.sendPosition(destNum: user.num, wantResponse: false) { + print("Position Sent") + } + } } }) {