forked from fritob/Camper-Monitor
CamperMonitor (Haupt-Repo) und VanAligneiOS (aus dem gemergten solar-integration-Branch) liefen unter zwei verschiedenen internen Namen, obwohl die App nach aussen längst einheitlich "VanControl Pro" heisst. Jetzt durchgängig VanControl: - Ordner: CamperMonitor/, CamperMonitorWatch/, CamperMonitorComplication/, VanAligneiOSWidget/ → VanControl/, VanControlWatch/, VanControlComplication/, VanControlWidget/ - Xcode-Projekt: CamperMonitor.xcodeproj → VanControl.xcodeproj, alle Targets/Schemes/Produktnamen entsprechend umbenannt - Bundle-Identifier auf Wunsch mitgeändert: de.s0.fototeddy.VanControl* (App noch nicht veröffentlicht); dabei auch die WKCompanionAppBundleIdentifier-Werte korrigiert, die noch das alte de.fritob-Präfix statt des tatsächlichen de.s0.fototeddy-Präfixes trugen - Swift-Dateien/Typen: CamperMonitorApp → VanControlApp, VanAligneiOSWidget* → VanControlWidget* - Config/*-Info.plist umbenannt, README.md/Tools/README.md/run-tests.sh auf die neuen Pfade angepasst Bewusst unverändert: firmware/vanalign und alle Bezüge auf "VanAlign" als Namen der Neigungsmesser-Hardware (eigenständiges Produkt, kein App-Name) sowie der komplette Android/-Ordner. Build (App, Watch, Debug) und Protokoll-Testlauf grün. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
49 lines
2.0 KiB
Swift
49 lines
2.0 KiB
Swift
import SwiftUI
|
||
|
||
/// VanControl Pro am Handgelenk.
|
||
///
|
||
/// Zwei Quellen, jede dort, wo sie hingehört:
|
||
///
|
||
/// * Der **Neigungsmesser** hängt direkt an der Uhr (`WatchLevelRadio`). Die
|
||
/// Nivellierung braucht damit kein geöffnetes iPhone – und genau dafür hebt
|
||
/// man beim Rangieren den Arm.
|
||
/// * **Batterie, Solar und Kühlbox** kommen über das iPhone (`PhoneLink`),
|
||
/// weil dort die Schlüssel liegen und die Geräte nur eine Verbindung
|
||
/// zulassen.
|
||
@main
|
||
struct CamperWatchApp: App {
|
||
@State private var link = PhoneLink()
|
||
@State private var radio = WatchLevelRadio()
|
||
@Environment(\.scenePhase) private var scenePhase
|
||
|
||
var body: some Scene {
|
||
WindowGroup {
|
||
WatchRootView()
|
||
.environment(link)
|
||
.environment(radio)
|
||
.task {
|
||
link.activate()
|
||
radio.start()
|
||
// Beim Start meldet `onChange` nichts: Die Bildschirmphase
|
||
// steht schon auf „aktiv“ und ändert sich nicht mehr. Ohne
|
||
// diese Zeile bliebe der schnelle Takt des iPhones aus, bis
|
||
// die App einmal im Hintergrund war.
|
||
link.setLive(true)
|
||
}
|
||
// Die Einbaulage kommt bevorzugt aus dem Sensor selbst. Nur
|
||
// falls dort noch nichts steht – ältere Firmware, oder nie
|
||
// bestimmt –, gilt, was das iPhone meldet.
|
||
.onChange(of: link.payload?.levelDevice?.orientation) { _, orientation in
|
||
guard let orientation, !radio.hasDeviceOrientation else { return }
|
||
radio.orientation = orientation
|
||
}
|
||
}
|
||
.onChange(of: scenePhase) { _, phase in
|
||
// Beides kostet Strom und lohnt nur, solange jemand hinschaut.
|
||
// Genau das sagt die Bildschirmphase aus.
|
||
link.setLive(phase == .active)
|
||
if phase == .active { radio.start() } else { radio.stop() }
|
||
}
|
||
}
|
||
}
|