banyaro-ios/BanYaroGo/BanYaroGoApp.swift
rene 7848817cbe GPX-Import via Teilen-Menü und 'Öffnen mit'
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
2026-05-30 14:34:40 +02:00

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
}