mirror of
https://github.com/StikDebug/StikDebug.git
synced 2026-10-15 20:10:30 +00:00
fix: require a background keep alive
This commit is contained in:
parent
2d09a405de
commit
6a078be17e
3 changed files with 86 additions and 30 deletions
|
|
@ -29,10 +29,15 @@ enum AppBootstrapper {
|
|||
}
|
||||
|
||||
private static func startConfiguredKeepAliveServices() {
|
||||
guard UserDefaults.standard.bool(forKey: "keepAliveAudio") else {
|
||||
return
|
||||
let defaults = UserDefaults.standard
|
||||
if defaults.bool(forKey: "keepAliveAudio") {
|
||||
BackgroundAudioManager.shared.start()
|
||||
} else if defaults.bool(forKey: "keepAliveLocation") {
|
||||
BackgroundLocationManager.shared.start()
|
||||
} else {
|
||||
defaults.set(true, forKey: "keepAliveAudio")
|
||||
BackgroundAudioManager.shared.start()
|
||||
}
|
||||
BackgroundAudioManager.shared.start()
|
||||
}
|
||||
|
||||
private static func applyDocumentPickerCopyWorkaround() {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ final class BackgroundLocationManager: NSObject, CLLocationManagerDelegate {
|
|||
|
||||
private let locationManager = CLLocationManager()
|
||||
private var isRunning = false
|
||||
private var persistentEnabled = false
|
||||
private var activityCount = 0
|
||||
|
||||
private override init() {
|
||||
|
|
@ -22,7 +23,35 @@ final class BackgroundLocationManager: NSObject, CLLocationManagerDelegate {
|
|||
}
|
||||
|
||||
func start() {
|
||||
isRunning = true
|
||||
persistentEnabled = true
|
||||
refreshRunningState()
|
||||
}
|
||||
|
||||
func stop() {
|
||||
persistentEnabled = false
|
||||
refreshRunningState()
|
||||
}
|
||||
|
||||
func requestStart() {
|
||||
activityCount += 1
|
||||
refreshRunningState()
|
||||
}
|
||||
|
||||
func requestStop() {
|
||||
activityCount = max(activityCount - 1, 0)
|
||||
refreshRunningState()
|
||||
}
|
||||
|
||||
private func refreshRunningState() {
|
||||
let shouldRun = persistentEnabled || (activityCount > 0 && UserDefaults.standard.bool(forKey: "keepAliveLocation"))
|
||||
guard shouldRun != isRunning else { return }
|
||||
|
||||
isRunning = shouldRun
|
||||
guard shouldRun else {
|
||||
locationManager.stopUpdatingLocation()
|
||||
return
|
||||
}
|
||||
|
||||
switch locationManager.authorizationStatus {
|
||||
case .authorizedAlways:
|
||||
locationManager.startUpdatingLocation()
|
||||
|
|
@ -30,27 +59,10 @@ final class BackgroundLocationManager: NSObject, CLLocationManagerDelegate {
|
|||
locationManager.requestAlwaysAuthorization()
|
||||
case .notDetermined:
|
||||
locationManager.requestAlwaysAuthorization()
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func stop() {
|
||||
isRunning = false
|
||||
locationManager.stopUpdatingLocation()
|
||||
}
|
||||
|
||||
func requestStart() {
|
||||
activityCount += 1
|
||||
if activityCount == 1, UserDefaults.standard.bool(forKey: "keepAliveLocation") {
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
func requestStop() {
|
||||
activityCount = max(activityCount - 1, 0)
|
||||
if activityCount == 0 {
|
||||
stop()
|
||||
case .denied, .restricted:
|
||||
restoreAudioFallback()
|
||||
@unknown default:
|
||||
restoreAudioFallback()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -59,11 +71,22 @@ final class BackgroundLocationManager: NSObject, CLLocationManagerDelegate {
|
|||
switch manager.authorizationStatus {
|
||||
case .authorizedAlways, .authorizedWhenInUse:
|
||||
manager.startUpdatingLocation()
|
||||
default:
|
||||
break
|
||||
case .denied, .restricted:
|
||||
restoreAudioFallback()
|
||||
case .notDetermined:
|
||||
return
|
||||
@unknown default:
|
||||
restoreAudioFallback()
|
||||
}
|
||||
}
|
||||
|
||||
private func restoreAudioFallback() {
|
||||
persistentEnabled = false
|
||||
isRunning = activityCount > 0 && UserDefaults.standard.bool(forKey: "keepAliveLocation")
|
||||
UserDefaults.standard.set(true, forKey: "keepAliveAudio")
|
||||
BackgroundAudioManager.shared.start()
|
||||
}
|
||||
|
||||
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
|
||||
// Location fixes may fail (e.g. no GPS indoors) — that's fine.
|
||||
// The manager just needs to be running, not actually fix a location.
|
||||
|
|
|
|||
|
|
@ -95,8 +95,7 @@ struct SettingsView: View {
|
|||
}
|
||||
}
|
||||
.onChange(of: keepAliveAudio) { _, enabled in
|
||||
if enabled { BackgroundAudioManager.shared.start() }
|
||||
else { BackgroundAudioManager.shared.stop() }
|
||||
handleAudioKeepAliveChange(enabled)
|
||||
}
|
||||
|
||||
Toggle(isOn: $keepAliveLocation) {
|
||||
|
|
@ -107,7 +106,7 @@ struct SettingsView: View {
|
|||
}
|
||||
}
|
||||
.onChange(of: keepAliveLocation) { _, enabled in
|
||||
if !enabled { BackgroundLocationManager.shared.stop() }
|
||||
handleLocationKeepAliveChange(enabled)
|
||||
}
|
||||
|
||||
} header: {
|
||||
|
|
@ -242,6 +241,35 @@ struct SettingsView: View {
|
|||
return "Version \(appVersion) • iOS \(UIDevice.current.systemVersion) • \(txmLabel)"
|
||||
}
|
||||
|
||||
private func handleAudioKeepAliveChange(_ enabled: Bool) {
|
||||
if enabled {
|
||||
BackgroundAudioManager.shared.start()
|
||||
BackgroundLocationManager.shared.stop()
|
||||
return
|
||||
}
|
||||
|
||||
if !keepAliveLocation {
|
||||
keepAliveLocation = true
|
||||
}
|
||||
BackgroundAudioManager.shared.stop()
|
||||
BackgroundLocationManager.shared.start()
|
||||
}
|
||||
|
||||
private func handleLocationKeepAliveChange(_ enabled: Bool) {
|
||||
if enabled {
|
||||
if !keepAliveAudio {
|
||||
BackgroundLocationManager.shared.start()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
BackgroundLocationManager.shared.stop()
|
||||
if !keepAliveAudio {
|
||||
keepAliveAudio = true
|
||||
BackgroundAudioManager.shared.start()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Business Logic
|
||||
|
||||
private func openAppFolder() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue