App Group group.app.banyaro.ios verbindet App und Widget-Extension (Entitlements in beiden Targets, CODE_SIGN_ENTITLEMENTS fürs Widget). Home-Screen-Widget (D): - BanYaroHomeWidget (klein + mittel): Tagesfoto, Hundename, nächster Termin. - App schreibt beim Heim-Laden einen Snapshot (HomeWidgetData) in die App Group und triggert WidgetCenter-Reload; Snapshot wird bei Logout/401 geleert. Siri-/Kurzbefehl (E): - StartWalkIntent „Gassi gehen" + AppShortcutsProvider (öffnet die App). - WalkLauncher überbrückt Intent → UI: Flag in der App Group, beim Aktivwerden eingelöst → Aufnehmen-Tab + Aufnahme-Start (TrackingView.startFresh). - MainTabView mit Tab-Auswahl (Tags), BanYaroGoApp liest scenePhase.
59 lines
1.9 KiB
Swift
59 lines
1.9 KiB
Swift
import SwiftUI
|
|
import SwiftData
|
|
|
|
@main
|
|
struct BanYaroGoApp: App {
|
|
@Environment(\.scenePhase) private var scenePhase
|
|
@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)
|
|
.onChange(of: scenePhase) { _, phase in
|
|
if phase == .active { WalkLauncher.shared.consumePendingFlag() }
|
|
}
|
|
.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,
|
|
CachedRoute.self, CachedDiaryEntry.self, CachedImage.self,
|
|
PendingRoute.self, PendingRoutePhoto.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
|
|
}
|