Meshtastic-Apple/Meshtastic/AppIntents/NavigateToNodeIntent.swift

65 lines
1.9 KiB
Swift
Raw Permalink Normal View History

2025-02-09 11:29:24 -08:00
//
// NavigateToNodeIntent.swift
// Meshtastic
//
// Created by Benjamin Faershtein on 2/8/25.
//
import Foundation
import AppIntents
import CoreLocation
2026-04-16 12:10:00 -07:00
import SwiftData
2025-02-09 11:29:24 -08:00
import UIKit
@available(iOS 16.4, *)
struct NavigateToNodeIntent: ForegroundContinuableIntent {
2025-04-27 14:04:47 -07:00
2025-02-09 11:29:24 -08:00
static var title: LocalizedStringResource = "Navigate to Node Position"
static var openAppWhenRun: Bool = false
2025-04-27 14:04:47 -07:00
2025-02-09 11:29:24 -08:00
@Parameter(title: "Node Number")
var nodeNum: Int
2025-04-27 14:04:47 -07:00
2025-02-09 11:29:24 -08:00
@MainActor
func perform() async throws -> some IntentResult & ProvidesDialog {
if !BLEManager.shared.isConnected {
throw AppIntentErrors.AppIntentError.notConnected
}
2025-04-27 14:04:47 -07:00
2026-04-16 12:10:00 -07:00
let nodeNumInt64 = Int64(nodeNum)
var descriptor = FetchDescriptor<NodeInfoEntity>(
predicate: #Predicate<NodeInfoEntity> { $0.num == nodeNumInt64 }
)
descriptor.fetchLimit = 1
2025-04-27 14:04:47 -07:00
2025-02-09 11:29:24 -08:00
do {
2026-04-16 12:10:00 -07:00
let fetchedNode = try await MainActor.run { try PersistenceController.shared.context.fetch(descriptor) }
guard fetchedNode.count == 1 else {
2025-02-09 11:29:24 -08:00
throw $nodeNum.needsValueError("Could not find node")
}
2025-04-27 14:04:47 -07:00
2025-02-09 11:29:24 -08:00
let nodeInfo = fetchedNode[0]
if let latitude = nodeInfo.latestPosition?.coordinate.latitude,
let longitude = nodeInfo.latestPosition?.coordinate.longitude {
2025-04-27 14:04:47 -07:00
2025-02-09 11:29:24 -08:00
let url = URL(string: "maps://?saddr=&daddr=\(latitude),\(longitude)")
2025-04-27 14:04:47 -07:00
2025-02-09 11:29:24 -08:00
if let mapURL = url, UIApplication.shared.canOpenURL(mapURL) {
// Request to continue in foreground before opening the app
try await requestToContinueInForeground()
2025-04-27 14:04:47 -07:00
2025-02-09 11:29:24 -08:00
// Open Apple Maps for navigation
UIApplication.shared.open(mapURL, options: [:], completionHandler: nil)
return .result(dialog: "Navigating to node location.")
} else {
throw AppIntentErrors.AppIntentError.message("Unable to open Apple Maps.")
}
} else {
throw AppIntentErrors.AppIntentError.message("Node does not have a recorded position.")
}
} catch {
throw AppIntentErrors.AppIntentError.message("Failed to fetch node data.")
}
}
}