This commit is contained in:
Garth Vander Houwen 2023-03-06 15:30:10 -08:00
parent 05c00aeb20
commit b7a68ddbc7
15 changed files with 132 additions and 78 deletions

View file

@ -861,7 +861,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export PATH=\"$PATH:/opt/homebrew/bin\"\nif which swiftlint > /dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https: //github.com/realm/SwiftLint\"\nfi\n";
};
/* End PBXShellScriptBuildPhase section */

View file

@ -561,7 +561,9 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
fetchBCUserRequest.predicate = NSPredicate(format: "num == %lld", Int64(emptyNodeNum))
do {
let fetchedUser = try context?.fetch(fetchBCUserRequest) as! [UserEntity]
guard let fetchedUser = try context?.fetch(fetchBCUserRequest) as? [UserEntity] else {
return
}
if fetchedUser.count > 0 {
context?.delete(fetchedUser[0])
print("🗑️ Deleted the All - Broadcast User")
@ -639,8 +641,9 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
do {
let fetchedUsers = try context?.fetch(messageUsers) as! [UserEntity]
guard let fetchedUsers = try context?.fetch(messageUsers) as? [UserEntity] else {
return false
}
if fetchedUsers.isEmpty {
print("🚫 Message Users Not Found, Fail")
@ -980,10 +983,13 @@ class BLEManager: NSObject, CBPeripheralDelegate, ObservableObject {
fetchMyInfoRequest.predicate = NSPredicate(format: "myNodeNum == %lld", Int64(connectedPeripheral.num))
do {
let fetchedMyInfo = try context!.fetch(fetchMyInfoRequest) as! [MyInfoEntity]
guard let fetchedMyInfo = try context!.fetch(fetchMyInfoRequest) as? [MyInfoEntity] else {
return false
}
if fetchedMyInfo.count == 1 {
let mutableChannels = fetchedMyInfo[0].channels!.mutableCopy() as! NSMutableOrderedSet
guard let mutableChannels = fetchedMyInfo[0].channels!.mutableCopy() as? NSMutableOrderedSet else {
return false
}
mutableChannels.removeAllObjects()
fetchedMyInfo[0].channels = mutableChannels
do {

View file

@ -54,7 +54,7 @@ extension Float {
let localeUnit = locale.object(forKey: NSLocale.Key(rawValue: "kCFLocaleTemperatureUnitKey"))
var format: UnitTemperature = .celsius
if localeUnit! as! String == "Fahrenheit" {
if localeUnit! as? String == "Fahrenheit" {
format = .fahrenheit
}
return temperature.converted(to: format).value

View file

@ -83,7 +83,9 @@ func myInfoPacket (myInfo: MyNodeInfo, peripheralId: String, context: NSManagedO
fetchMyInfoRequest.predicate = NSPredicate(format: "myNodeNum == %lld", Int64(myInfo.myNodeNum))
do {
let fetchedMyInfo = try context.fetch(fetchMyInfoRequest) as! [MyInfoEntity]
guard let fetchedMyInfo = try context.fetch(fetchMyInfoRequest) as? [MyInfoEntity] else {
return nil
}
// Not Found Insert
if fetchedMyInfo.isEmpty {
@ -151,8 +153,9 @@ func channelPacket (channel: Channel, fromNum: Int64, context: NSManagedObjectCo
fetchedMyInfoRequest.predicate = NSPredicate(format: "myNodeNum == %lld", fromNum)
do {
let fetchedMyInfo = try context.fetch(fetchedMyInfoRequest) as! [MyInfoEntity]
guard let fetchedMyInfo = try context.fetch(fetchedMyInfoRequest) as? [MyInfoEntity] else {
return
}
if fetchedMyInfo.count == 1 {
let newChannel = ChannelEntity(context: context)
newChannel.id = Int32(channel.index)
@ -162,7 +165,9 @@ func channelPacket (channel: Channel, fromNum: Int64, context: NSManagedObjectCo
newChannel.name = channel.settings.name
newChannel.role = Int32(channel.role.rawValue)
newChannel.psk = channel.settings.psk
let mutableChannels = fetchedMyInfo[0].channels!.mutableCopy() as! NSMutableOrderedSet
guard let mutableChannels = fetchedMyInfo[0].channels!.mutableCopy() as? NSMutableOrderedSet else {
return
}
if mutableChannels.contains(newChannel) {
mutableChannels.replaceObject(at: Int(newChannel.index), with: newChannel)
} else {
@ -199,8 +204,9 @@ func deviceMetadataPacket (metadata: DeviceMetadata, fromNum: Int64, context: NS
fetchedNodeRequest.predicate = NSPredicate(format: "num == %lld", fromNum)
do {
let fetchedNode = try context.fetch(fetchedNodeRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchedNodeRequest) as? [NodeInfoEntity] else {
return
}
if fetchedNode.count > 0 {
let newMetadata = DeviceMetadataEntity(context: context)
newMetadata.firmwareVersion = metadata.firmwareVersion
@ -239,8 +245,9 @@ func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObje
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeInfo.num))
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] else {
return nil
}
// Not Found Insert
if fetchedNode.isEmpty && nodeInfo.hasUser {
@ -293,8 +300,9 @@ func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObje
fetchMyInfoRequest.predicate = NSPredicate(format: "myNodeNum == %lld", Int64(nodeInfo.num))
do {
let fetchedMyInfo = try context.fetch(fetchMyInfoRequest) as! [MyInfoEntity]
guard let fetchedMyInfo = try context.fetch(fetchMyInfoRequest) as? [MyInfoEntity] else {
return nil
}
if fetchedMyInfo.count > 0 {
newNode.myInfo = fetchedMyInfo[0]
}
@ -359,7 +367,9 @@ func nodeInfoPacket (nodeInfo: NodeInfo, channel: UInt32, context: NSManagedObje
fetchMyInfoRequest.predicate = NSPredicate(format: "myNodeNum == %lld", Int64(nodeInfo.num))
do {
let fetchedMyInfo = try context.fetch(fetchMyInfoRequest) as! [MyInfoEntity]
guard let fetchedMyInfo = try context.fetch(fetchMyInfoRequest) as? [MyInfoEntity] else {
return nil
}
if fetchedMyInfo.count > 0 {
fetchedNode[0].myInfo = fetchedMyInfo[0]
}
@ -456,7 +466,9 @@ func adminAppPacket (packet: MeshPacket, context: NSManagedObjectContext) {
fetchNodeRequest.predicate = NSPredicate(format: "num == %lld", Int64(packet.from))
do {
let fetchedNode = try context.fetch(fetchNodeRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodeRequest) as? [NodeInfoEntity] else {
return
}
if fetchedNode.count == 1 {
let messages = String(cmmc.textFormatString())
.replacingOccurrences(of: "11: ", with: "")
@ -541,7 +553,9 @@ func adminResponseAck (packet: MeshPacket, context: NSManagedObjectContext) {
let fetchedAdminMessageRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "MessageEntity")
fetchedAdminMessageRequest.predicate = NSPredicate(format: "messageId == %lld", packet.decoded.requestID)
do {
let fetchedMessage = try context.fetch(fetchedAdminMessageRequest) as! [MessageEntity]
guard let fetchedMessage = try context.fetch(fetchedAdminMessageRequest) as? [MessageEntity] else {
return
}
if fetchedMessage.count > 0 {
fetchedMessage[0].ackTimestamp = Int32(Date().timeIntervalSince1970)
fetchedMessage[0].ackError = Int32(RoutingError.none.rawValue)
@ -648,7 +662,9 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage
do {
let fetchedNode = try context.fetch(fetchNodeTelemetryRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodeTelemetryRequest) as? [NodeInfoEntity] else {
return
}
if fetchedNode.count == 1 {
if telemetryMessage.variant == Telemetry.OneOf_Variant.deviceMetrics(telemetryMessage.deviceMetrics) {
// Device Metrics
@ -738,10 +754,10 @@ func textMessageAppPacket(packet: MeshPacket, connectedNode: Int64, context: NSM
let messageUsers: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "UserEntity")
messageUsers.predicate = NSPredicate(format: "num IN %@", [packet.to, packet.from])
do {
let fetchedUsers = try context.fetch(messageUsers) as! [UserEntity]
guard let fetchedUsers = try context.fetch(messageUsers) as? [UserEntity] else {
return
}
let newMessage = MessageEntity(context: context)
newMessage.messageId = Int64(packet.id)
newMessage.messageTimestamp = Int32(bitPattern: packet.rxTime)
@ -794,7 +810,9 @@ func textMessageAppPacket(packet: MeshPacket, connectedNode: Int64, context: NSM
fetchMyInfoRequest.predicate = NSPredicate(format: "myNodeNum == %lld", Int64(connectedNode))
do {
let fetchedMyInfo = try context.fetch(fetchMyInfoRequest) as! [MyInfoEntity]
guard let fetchedMyInfo = try context.fetch(fetchMyInfoRequest) as? [MyInfoEntity] else {
return
}
for channel in (fetchedMyInfo[0].channels?.array ?? []) as? [ChannelEntity] ?? [] {
if channel.index == newMessage.channel {
context.refresh(channel, mergeChanges: true)
@ -841,8 +859,9 @@ func waypointPacket (packet: MeshPacket, context: NSManagedObjectContext) {
do {
if let waypointMessage = try? Waypoint(serializedData: packet.decoded.payload) {
let fetchedWaypoint = try context.fetch(fetchWaypointRequest) as! [WaypointEntity]
guard let fetchedWaypoint = try context.fetch(fetchWaypointRequest) as? [WaypointEntity] else {
return
}
if fetchedWaypoint.isEmpty {
let waypoint = WaypointEntity(context: context)

View file

@ -13,9 +13,11 @@ public func getNodeInfo(id: Int64, context: NSManagedObjectContext) -> NodeInfoE
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(id))
do {
let fetchNodeInfo = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
if fetchNodeInfo.count == 1 {
return fetchNodeInfo[0]
guard let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] else {
return nil
}
if fetchedNode.count == 1 {
return fetchedNode[0]
}
} catch {
return nil
@ -29,7 +31,9 @@ public func getUser(id: Int64, context: NSManagedObjectContext) -> UserEntity {
fetchUserRequest.predicate = NSPredicate(format: "num == %lld", Int64(id))
do {
let fetchedUser = try context.fetch(fetchUserRequest) as! [UserEntity]
guard let fetchedUser = try context.fetch(fetchUserRequest) as? [UserEntity] else {
return UserEntity(context: context)
}
if fetchedUser.count == 1 {
return fetchedUser[0]
}
@ -45,7 +49,9 @@ public func getWaypoint(id: Int64, context: NSManagedObjectContext) -> WaypointE
fetchWaypointRequest.predicate = NSPredicate(format: "id == %lld", Int64(id))
do {
let fetchedWaypoint = try context.fetch(fetchWaypointRequest) as! [WaypointEntity]
guard let fetchedWaypoint = try context.fetch(fetchWaypointRequest) as? [WaypointEntity] else {
return WaypointEntity(context: context)
}
if fetchedWaypoint.count == 1 {
return fetchedWaypoint[0]
}

View file

@ -12,12 +12,11 @@ public func clearPositions(destNum: Int64, context: NSManagedObjectContext) -> B
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(destNum))
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] else {
return false
}
let newPostions = [PositionEntity]()
fetchedNode[0].positions? = NSOrderedSet(array: newPostions)
do {
try context.save()
return true
@ -26,7 +25,6 @@ public func clearPositions(destNum: Int64, context: NSManagedObjectContext) -> B
context.rollback()
return false
}
} catch {
print("💥 Fetch NodeInfoEntity Error")
return false
@ -39,12 +37,11 @@ public func clearTelemetry(destNum: Int64, metricsType: Int32, context: NSManage
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(destNum))
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] else {
return false
}
let emptyTelemetry = [TelemetryEntity]()
fetchedNode[0].telemetries? = NSOrderedSet(array: emptyTelemetry)
do {
try context.save()
return true
@ -53,7 +50,6 @@ public func clearTelemetry(destNum: Int64, metricsType: Int32, context: NSManage
context.rollback()
return false
}
} catch {
print("💥 Fetch NodeInfoEntity Error")
return false
@ -115,13 +111,18 @@ func upsertPositionPacket (packet: MeshPacket, context: NSManagedObjectContext)
// Don't save empty position packets
if positionMessage.longitudeI > 0 || positionMessage.latitudeI > 0 && (positionMessage.latitudeI != 373346000 && positionMessage.longitudeI != -1220090000) {
let fetchedNode = try context.fetch(fetchNodePositionRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodePositionRequest) as? [NodeInfoEntity] else {
return
}
if fetchedNode.count == 1 {
// Unset the current latest position for this node
let fetchCurrentLatestPositionsRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "PositionEntity")
fetchCurrentLatestPositionsRequest.predicate = NSPredicate(format: "nodePosition.num == %lld && latest = true", Int64(packet.from))
let fetchedPositions = try context.fetch(fetchCurrentLatestPositionsRequest) as! [PositionEntity]
guard let fetchedPositions = try context.fetch(fetchCurrentLatestPositionsRequest) as? [PositionEntity] else {
return
}
if fetchedPositions.count > 0 {
for position in fetchedPositions {
position.latest = false
@ -143,8 +144,9 @@ func upsertPositionPacket (packet: MeshPacket, context: NSManagedObjectContext)
} else {
position.time = Date(timeIntervalSince1970: TimeInterval(Int64(positionMessage.time)))
}
let mutablePositions = fetchedNode[0].positions!.mutableCopy() as! NSMutableOrderedSet
guard let mutablePositions = fetchedNode[0].positions!.mutableCopy() as? NSMutableOrderedSet else {
return
}
mutablePositions.add(position)
fetchedNode[0].id = Int64(packet.from)
fetchedNode[0].num = Int64(packet.from)
@ -163,7 +165,7 @@ func upsertPositionPacket (packet: MeshPacket, context: NSManagedObjectContext)
}
} else {
print("💥 Empty POSITION_APP Packet")
print(try! packet.jsonString())
print((try? packet.jsonString()) ?? "JSON Decode Failure")
}
}
} catch {
@ -180,8 +182,9 @@ func upsertBluetoothConfigPacket(config: Meshtastic.Config.BluetoothConfig, node
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] else {
return
}
// Found a node, save Device Config
if !fetchedNode.isEmpty {
if fetchedNode[0].bluetoothConfig == nil {
@ -220,8 +223,9 @@ func upsertDeviceConfigPacket(config: Meshtastic.Config.DeviceConfig, nodeNum: I
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] else {
return
}
// Found a node, save Device Config
if !fetchedNode.isEmpty {
if fetchedNode[0].deviceConfig == nil {
@ -267,9 +271,9 @@ func upsertDisplayConfigPacket(config: Meshtastic.Config.DisplayConfig, nodeNum:
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(nodeNum))
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] else {
return
}
// Found a node, save Device Config
if !fetchedNode.isEmpty {
@ -330,7 +334,9 @@ func upsertLoRaConfigPacket(config: Meshtastic.Config.LoRaConfig, nodeNum: Int64
let fetchNodeInfoRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "NodeInfoEntity")
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", nodeNum)
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] else {
return
}
// Found a node, save LoRa Config
if fetchedNode.count > 0 {
if fetchedNode[0].loRaConfig == nil {
@ -393,7 +399,9 @@ func upsertNetworkConfigPacket(config: Meshtastic.Config.NetworkConfig, nodeNum:
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] else {
return
}
// Found a node, save WiFi Config
if !fetchedNode.isEmpty {
if fetchedNode[0].networkConfig == nil {
@ -438,7 +446,9 @@ func upsertPositionConfigPacket(config: Meshtastic.Config.PositionConfig, nodeNu
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] else {
return
}
// Found a node, save LoRa Config
if !fetchedNode.isEmpty {
if fetchedNode[0].positionConfig == nil {
@ -487,8 +497,9 @@ func upsertCannedMessagesModuleConfigPacket(config: Meshtastic.ModuleConfig.Cann
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] else {
return
}
// Found a node, save Canned Message Config
if !fetchedNode.isEmpty {
@ -550,7 +561,9 @@ func upsertExternalNotificationModuleConfigPacket(config: Meshtastic.ModuleConfi
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] else {
return
}
// Found a node, save External Notificaitone Config
if !fetchedNode.isEmpty {
@ -616,7 +629,9 @@ func upsertMqttModuleConfigPacket(config: Meshtastic.ModuleConfig.MQTTConfig, no
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] else {
return
}
// Found a node, save MQTT Config
if !fetchedNode.isEmpty {
@ -664,7 +679,9 @@ func upsertRangeTestModuleConfigPacket(config: Meshtastic.ModuleConfig.RangeTest
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] else {
return
}
// Found a node, save Device Config
if !fetchedNode.isEmpty {
if fetchedNode[0].rangeTestConfig == nil {
@ -705,7 +722,9 @@ func upsertSerialModuleConfigPacket(config: Meshtastic.ModuleConfig.SerialConfig
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] else {
return
}
// Found a node, save Device Config
if !fetchedNode.isEmpty {
@ -766,7 +785,9 @@ func upsertTelemetryModuleConfigPacket(config: Meshtastic.ModuleConfig.Telemetry
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] else {
return
}
// Found a node, save Telemetry Config
if !fetchedNode.isEmpty {

View file

@ -252,8 +252,9 @@ struct Connect: View {
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(bleManager.connectedPeripheral?.num ?? -1))
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] else {
return
}
// Found a node, check it for a region
if !fetchedNode.isEmpty {
node = fetchedNode[0]

View file

@ -152,8 +152,7 @@ struct ChannelMessageList: View {
Image(systemName: "trash")
}
}
let tapbacks = message.value(forKey: "tapbacks") as! [MessageEntity]
let tapbacks = message.value(forKey: "tapbacks") as? [MessageEntity] ?? []
if tapbacks.count > 0 {
VStack(alignment: .trailing) {
HStack {

View file

@ -257,7 +257,9 @@ struct Contacts: View {
let fetchNodeInfoRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "NodeInfoEntity")
fetchNodeInfoRequest.predicate = NSPredicate(format: "num == %lld", Int64(bleManager.connectedPeripheral?.num ?? -1))
do {
let fetchedNode = try context.fetch(fetchNodeInfoRequest) as! [NodeInfoEntity]
guard let fetchedNode = try context.fetch(fetchNodeInfoRequest) as? [NodeInfoEntity] else {
return
}
// Found a node, check it for a region
if !fetchedNode.isEmpty {
node = fetchedNode[0]

View file

@ -158,7 +158,7 @@ struct UserMessageList: View {
}
}
let tapbacks = message.value(forKey: "tapbacks") as! [MessageEntity]
let tapbacks = message.value(forKey: "tapbacks") as? [MessageEntity] ?? []
if tapbacks.count > 0 {
VStack(alignment: .trailing) {
HStack {

View file

@ -154,7 +154,7 @@ struct DeviceMetricsLog: View {
}
}
Button {
exportString = telemetryToCsvFile(telemetry: node.telemetries!.array as! [TelemetryEntity], metricsType: 0)
exportString = telemetryToCsvFile(telemetry: node.telemetries!.array as? [TelemetryEntity] ?? [], metricsType: 0)
isExporting = true
} label: {
Label("save", systemImage: "square.and.arrow.down")

View file

@ -138,7 +138,7 @@ struct EnvironmentMetricsLog: View {
}
}
Button {
exportString = telemetryToCsvFile(telemetry: node.telemetries!.array as! [TelemetryEntity], metricsType: 1)
exportString = telemetryToCsvFile(telemetry: node.telemetries!.array as? [TelemetryEntity] ?? [], metricsType: 1)
isExporting = true
} label: {
Label("save", systemImage: "square.and.arrow.down")

View file

@ -55,9 +55,8 @@ struct NodeDetail: View {
GeometryReader { bounds in
VStack {
if node.positions?.count ?? 0 > 0 {
// let mostRecent = node.positions?.lastObject as! PositionEntity
ZStack {
let annotations = node.positions?.array as! [PositionEntity]
let annotations = node.positions?.array as? [PositionEntity] ?? []
ZStack {
MapViewSwiftUI(onLongPress: { coord in
waypointCoordinate = coord

View file

@ -134,7 +134,7 @@ struct PositionLog: View {
Button {
exportString = positionToCsvFile(positions: node.positions!.array as! [PositionEntity])
exportString = positionToCsvFile(positions: node.positions!.array as? [PositionEntity] ?? [])
isExporting = true
} label: {

View file

@ -230,10 +230,11 @@ struct Channels: View {
channel.settings.psk = Data(base64Encoded: channelKey) ?? Data()
channel.settings.uplinkEnabled = uplink
channel.settings.downlinkEnabled = downlink
} else {
if channelIndex <= node!.myInfo!.channels?.count ?? 0 {
let channelEntity = node!.myInfo!.channels?[Int(channelIndex)] as! ChannelEntity
guard let channelEntity = node!.myInfo!.channels?[Int(channelIndex)] as? ChannelEntity else {
return
}
context.delete(channelEntity)
do {
try context.save()