diff --git a/Meshtastic Client.xcodeproj/project.pbxproj b/Meshtastic Client.xcodeproj/project.pbxproj index 374d17e4..0d2aa189 100644 --- a/Meshtastic Client.xcodeproj/project.pbxproj +++ b/Meshtastic Client.xcodeproj/project.pbxproj @@ -42,6 +42,8 @@ DDAF8C6B26ED0DD80058C060 /* environmental_measurement.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAF8C6A26ED0DD80058C060 /* environmental_measurement.pb.swift */; }; DDAF8C6E26ED19040058C060 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDAF8C6D26ED19040058C060 /* Extensions.swift */; }; DDB020A0272B0C6B00F8DBAE /* PersistanceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB0209F272B0C6B00F8DBAE /* PersistanceController.swift */; }; + DDB020A42733A6F400F8DBAE /* MeshtasticClient.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = DDB020A22733A6F400F8DBAE /* MeshtasticClient.xcdatamodeld */; }; + DDB020A92733AECE00F8DBAE /* NodeInfoEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB020A82733AECE00F8DBAE /* NodeInfoEntity.swift */; }; DDC2E15826CE248E0042C5E4 /* MeshtasticClientApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDC2E15726CE248E0042C5E4 /* MeshtasticClientApp.swift */; }; DDC2E15C26CE248F0042C5E4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDC2E15B26CE248F0042C5E4 /* Assets.xcassets */; }; DDC2E15F26CE248F0042C5E4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DDC2E15E26CE248F0042C5E4 /* Preview Assets.xcassets */; }; @@ -106,6 +108,9 @@ DDAF8C6A26ED0DD80058C060 /* environmental_measurement.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = environmental_measurement.pb.swift; sourceTree = ""; }; DDAF8C6D26ED19040058C060 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; DDB0209F272B0C6B00F8DBAE /* PersistanceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistanceController.swift; sourceTree = ""; }; + DDB020A1273396D800F8DBAE /* RELEASENOTES.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = RELEASENOTES.md; sourceTree = ""; }; + DDB020A32733A6F400F8DBAE /* MeshtasticClient.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = MeshtasticClient.xcdatamodel; sourceTree = ""; }; + DDB020A82733AECE00F8DBAE /* NodeInfoEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeInfoEntity.swift; sourceTree = ""; }; DDC2E15426CE248E0042C5E4 /* MeshtasticClient.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MeshtasticClient.app; sourceTree = BUILT_PRODUCTS_DIR; }; DDC2E15726CE248E0042C5E4 /* MeshtasticClientApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshtasticClientApp.swift; sourceTree = ""; }; DDC2E15B26CE248F0042C5E4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -206,6 +211,7 @@ isa = PBXGroup; children = ( DDB0209F272B0C6B00F8DBAE /* PersistanceController.swift */, + DDB020A82733AECE00F8DBAE /* NodeInfoEntity.swift */, ); path = Data; sourceTree = ""; @@ -245,6 +251,8 @@ DDC2E15B26CE248F0042C5E4 /* Assets.xcassets */, DDC2E16526CE248F0042C5E4 /* Info.plist */, DDC2E15D26CE248F0042C5E4 /* Preview Content */, + DDB020A1273396D800F8DBAE /* RELEASENOTES.md */, + DDB020A22733A6F400F8DBAE /* MeshtasticClient.xcdatamodeld */, ); path = MeshtasticClient; sourceTree = ""; @@ -494,6 +502,7 @@ DD23A51326FEF5D500D9B90C /* MessageData.swift in Sources */, DD836AED26F858F900ABCC23 /* MeshData.swift in Sources */, DDAF8C6B26ED0DD80058C060 /* environmental_measurement.pb.swift in Sources */, + DDB020A42733A6F400F8DBAE /* MeshtasticClient.xcdatamodeld in Sources */, DD90860C26F684AF00DC5189 /* BatteryIcon.swift in Sources */, DD4A91202708C66600501B7E /* Configuration.swift in Sources */, DD4A911E2708C65400501B7E /* AppSettings.swift in Sources */, @@ -501,6 +510,7 @@ DDF924CA26FBB953009FE055 /* ConnectedDevice.swift in Sources */, DDAF8C5D26ED09490058C060 /* portnums.pb.swift in Sources */, DD47E3DF26F39D9F00029299 /* MyInfoModel.swift in Sources */, + DDB020A92733AECE00F8DBAE /* NodeInfoEntity.swift in Sources */, DD23A50F26FD1B4400D9B90C /* PeripheralModel.swift in Sources */, DD47E3CE26F103C600029299 /* NodeList.swift in Sources */, DD47E3D026F1073F00029299 /* NodeRow.swift in Sources */, @@ -609,6 +619,7 @@ SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2,6"; }; name = Debug; }; @@ -660,9 +671,11 @@ IPHONEOS_DEPLOYMENT_TARGET = 15.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2,6"; VALIDATE_PRODUCT = YES; }; name = Release; @@ -684,11 +697,11 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.27.6; + MARKETING_VERSION = 1.27.7; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2,6"; }; @@ -711,11 +724,11 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.27.6; + MARKETING_VERSION = 1.27.7; PRODUCT_BUNDLE_IDENTIFIER = gvh.MeshtasticClient; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = YES; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2,6"; }; @@ -864,6 +877,19 @@ productName = SwiftProtobuf; }; /* End XCSwiftPackageProductDependency section */ + +/* Begin XCVersionGroup section */ + DDB020A22733A6F400F8DBAE /* MeshtasticClient.xcdatamodeld */ = { + isa = XCVersionGroup; + children = ( + DDB020A32733A6F400F8DBAE /* MeshtasticClient.xcdatamodel */, + ); + currentVersion = DDB020A32733A6F400F8DBAE /* MeshtasticClient.xcdatamodel */; + path = MeshtasticClient.xcdatamodeld; + sourceTree = ""; + versionGroupType = wrapper.xcdatamodel; + }; +/* End XCVersionGroup section */ }; rootObject = DDC2E14C26CE248E0042C5E4 /* Project object */; } diff --git a/MeshtasticClient/Helpers/BLEManager.swift b/MeshtasticClient/Helpers/BLEManager.swift index 215023cc..0ff498f6 100644 --- a/MeshtasticClient/Helpers/BLEManager.swift +++ b/MeshtasticClient/Helpers/BLEManager.swift @@ -20,8 +20,8 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph } } - @ObservedObject var meshData : MeshData - @ObservedObject var messageData : MessageData + @Published var meshData : MeshData + @Published var messageData : MessageData private var centralManager: CBCentralManager! @@ -72,7 +72,7 @@ class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeriph if central.state == .poweredOn { isSwitchedOn = true - startScanning() + //startScanning() } else { diff --git a/MeshtasticClient/Info.plist b/MeshtasticClient/Info.plist index 21a3f47f..636795eb 100644 --- a/MeshtasticClient/Info.plist +++ b/MeshtasticClient/Info.plist @@ -29,7 +29,7 @@ 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/MeshtasticClient.entitlements b/MeshtasticClient/MeshtasticClient.entitlements index a86982db..139f8289 100644 --- a/MeshtasticClient/MeshtasticClient.entitlements +++ b/MeshtasticClient/MeshtasticClient.entitlements @@ -10,5 +10,7 @@ com.apple.security.personal-information.location + com.apple.security.files.user-selected.read-write + diff --git a/MeshtasticClient/MeshtasticClient.xcdatamodeld/MeshtasticClient.xcdatamodel/contents b/MeshtasticClient/MeshtasticClient.xcdatamodeld/MeshtasticClient.xcdatamodel/contents new file mode 100644 index 00000000..3374cb84 --- /dev/null +++ b/MeshtasticClient/MeshtasticClient.xcdatamodeld/MeshtasticClient.xcdatamodel/contents @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/MeshtasticClient/Model/Data/NodeInfoEntity.swift b/MeshtasticClient/Model/Data/NodeInfoEntity.swift new file mode 100644 index 00000000..1c9ce351 --- /dev/null +++ b/MeshtasticClient/Model/Data/NodeInfoEntity.swift @@ -0,0 +1,16 @@ +import Foundation +import CoreData + +extension NodeInfoEntity { + @nonobjc public class func createFetchRequest() -> NSFetchRequest { + return NSFetchRequest(entityName: "NodeInfoEntity") + } + + + @NSManaged public var id: UInt32 + @NSManaged public var num: UInt32 + @NSManaged public var sha: String + @NSManaged public var url: String + + +} diff --git a/MeshtasticClient/RELEASENOTES.md b/MeshtasticClient/RELEASENOTES.md new file mode 100644 index 00000000..88cd628a --- /dev/null +++ b/MeshtasticClient/RELEASENOTES.md @@ -0,0 +1,7 @@ +# 1.27.8 + +* Update NodeList SwipeAction Button to be role: Destructive +* Added com.apple.security.files.user-selected.read-write entitlement to AppSandbox for MacOS for Mesh log download + + + diff --git a/MeshtasticClient/Views/Bluetooth/Connect.swift b/MeshtasticClient/Views/Bluetooth/Connect.swift index 46e7c457..ac9deb47 100644 --- a/MeshtasticClient/Views/Bluetooth/Connect.swift +++ b/MeshtasticClient/Views/Bluetooth/Connect.swift @@ -103,7 +103,6 @@ struct Connect: View { Button(role: .destructive) { if bleManager.connectedPeripheral != nil && bleManager.connectedPeripheral.peripheral.state == CBPeripheralState.connected { - bleManager.disconnectDevice() isPreferredRadio = false } diff --git a/MeshtasticClient/Views/Messages/Messages.swift b/MeshtasticClient/Views/Messages/Messages.swift index 82579ce7..664d6cb1 100644 --- a/MeshtasticClient/Views/Messages/Messages.swift +++ b/MeshtasticClient/Views/Messages/Messages.swift @@ -14,8 +14,10 @@ struct Messages: View { @State private var totalBytes = 0 @State private var lastTypingMessage = "" @FocusState private var focusedField: Field? + @Namespace var topId @Namespace var bottomId + @State var showDeleteMessageAlert = false @State private var deleteMessageId : UInt32 = 0 diff --git a/MeshtasticClient/Views/Nodes/NodeList.swift b/MeshtasticClient/Views/Nodes/NodeList.swift index ee5a28f4..d743819a 100644 --- a/MeshtasticClient/Views/Nodes/NodeList.swift +++ b/MeshtasticClient/Views/Nodes/NodeList.swift @@ -65,17 +65,15 @@ struct NodeList: View { } } - .swipeActions { - Button { - - let nodeIndex = bleManager.meshData.nodes.firstIndex(where: { $0.id == node.id }) - bleManager.meshData.nodes.remove(at: nodeIndex!) - bleManager.meshData.save() + .swipeActions (edge: .trailing) { + Button (role: .destructive) { + let nodeIndex = bleManager.meshData.nodes.firstIndex(where: { $0.num == node.num }) + bleManager.meshData.nodes.remove(at: nodeIndex!) + bleManager.meshData.save() } label: { Label("Delete from app", systemImage: "trash") - } - .tint(.red) + } } } } @@ -83,6 +81,7 @@ struct NodeList: View { .navigationTitle("All Nodes") .onAppear( perform: { + bleManager.meshData.load() if UIDevice.current.userInterfaceIdiom == .pad { if bleManager.meshData.nodes.count > 0 { selection = "0"