Andere Apps können jetzt GPX-Tracks zu Ban Yaro Go schicken (Komoot,
Outdooractive, GPSies, AllTrails, Files-App, Mail-Anhänge, AirDrop).
- Info.plist:
- UTImportedTypeDeclarations: com.topografix.gpx (conforms to
public.xml/data/content, ext gpx, MIME application/gpx+xml)
- CFBundleDocumentTypes registriert die UTI als Viewer (LSHandlerRank
Alternate, damit wir nicht die Default-App werden)
- LSSupportsOpeningDocumentsInPlace=true
- Support/GPXParser.swift: schlanker XMLParser/SAX-Reader für
<trkpt>/<wpt>/<rtept>, Track-Name aus <trk><name>, ele + ISO8601 time
- Views/GPXImportSheet.swift: Sheet mit Map(MapPolyline)+Start/Ziel-Pins,
Distanz/Punkte/Dauer-Karte, zwei Aktionen:
1. 'Als Tour übernehmen' — Name editierbar, Hunde-Picker (FlowDogs),
öffentlich-Toggle → POST /api/routes
2. 'Nur ansehen' — Startpunkt in Apple Maps
- BanYaroGoApp.swift: .onOpenURL prüft .gpx, security-scoped resource,
parst und triggert das Sheet via TrackBox-Wrapper
51 lines
1.6 KiB
Swift
51 lines
1.6 KiB
Swift
import SwiftUI
|
|
import SwiftData
|
|
|
|
@main
|
|
struct BanYaroGoApp: App {
|
|
@State private var auth = AuthSession()
|
|
@State private var activeDog = ActiveDogStore()
|
|
@State private var pendingGPX: GPXTrack?
|
|
|
|
var body: some Scene {
|
|
WindowGroup {
|
|
RootView()
|
|
.environment(auth)
|
|
.environment(activeDog)
|
|
.onOpenURL { url in
|
|
handleIncoming(url: url)
|
|
}
|
|
.sheet(item: Binding(
|
|
get: { pendingGPX.map { TrackBox(track: $0) } },
|
|
set: { pendingGPX = $0?.track }
|
|
)) { box in
|
|
GPXImportSheet(track: box.track) {
|
|
pendingGPX = nil
|
|
}
|
|
}
|
|
}
|
|
.modelContainer(for: [ActiveWalk.self, PhotoLocation.self])
|
|
}
|
|
|
|
private func handleIncoming(url: URL) {
|
|
// Nur GPX akzeptieren — andere URLs (Deep-Links) sind anderweitig verdrahtet.
|
|
guard url.pathExtension.lowercased() == "gpx" else { return }
|
|
|
|
let didAccess = url.startAccessingSecurityScopedResource()
|
|
defer { if didAccess { url.stopAccessingSecurityScopedResource() } }
|
|
|
|
do {
|
|
let data = try Data(contentsOf: url)
|
|
let track = try GPXParser.parse(data: data)
|
|
pendingGPX = track
|
|
} catch {
|
|
print("GPX-Import fehlgeschlagen: \(error)")
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Hilfs-Wrapper, damit GPXTrack als `Identifiable` in `.sheet(item:)` taugt.
|
|
private struct TrackBox: Identifiable {
|
|
let id = UUID()
|
|
let track: GPXTrack
|
|
}
|