Files
ABS-Client/ABS Client/Audiobookshelf swift/Audiobookshelf_swiftApp.swift
Scarriffle 134482bb4a Enhance download notifications and settings; add support for live activities
- Updated notification body to use proper German quotation marks for download failure alerts.
- Refactored audio interruption handling in PlayerEngine to utilize MainActor.assumeIsolated for better performance.
- Introduced nonisolated properties for support and downloads directories in ProgressSyncManager.
- Improved FullHistoryView and MainView with additional toolbar items and alerts for download failures.
- Added new toggles in SettingsView for parallel downloads and mobile data usage.
- Created new color assets for the DownloadWidgetExtension and updated widget appearance.
- Implemented Info.plist for DownloadWidgetExtension to support widget functionality.
- Enabled live activities support in iOS Info.plist.
2026-06-08 19:32:54 +02:00

82 lines
2.6 KiB
Swift

import SwiftUI
#if os(iOS)
import AVFAudio
import UIKit
#endif
@main
struct Audiobookshelf_swiftApp: App {
@State private var appState = AppState()
#if os(iOS)
/// Bridges the UIKit-only `handleEventsForBackgroundURLSession` callback
/// (used by iOS to wake the app when a background download completes)
/// into the SwiftUI lifecycle. Without this, in-flight downloads can't
/// notify the app of completion after a swipe-away.
@UIApplicationDelegateAdaptor(BackgroundDownloadAppDelegate.self) private var appDelegate
#endif
init() {
configureImageCache()
#if os(iOS)
configureAudioSession()
#endif
}
/// Increases the shared URLCache so AsyncImage covers persist across renders
/// and app launches. Default capacity is tiny (~4 MB / 20 MB).
private func configureImageCache() {
let memoryCapacity = 50 * 1024 * 1024 // 50 MB
let diskCapacity = 500 * 1024 * 1024 // 500 MB
URLCache.shared = URLCache(
memoryCapacity: memoryCapacity,
diskCapacity: diskCapacity,
diskPath: "covers"
)
}
var body: some Scene {
#if os(macOS)
WindowGroup {
ContentView()
.environment(appState)
}
.windowResizability(.contentSize)
Settings {
SettingsView()
.environment(appState)
}
#else
WindowGroup {
ContentView()
.environment(appState)
}
#endif
}
#if os(iOS)
private func configureAudioSession() {
// Nur die Kategorie registrieren setActive(true) passiert erst in play(),
// damit beim App-Start keine laufende Fremd-Wiedergabe unterbrochen wird.
try? AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [])
}
#endif
}
#if os(iOS)
/// Receives the system's background URLSession completion callback and routes
/// the handler to whichever `DownloadManager` is currently active. We can't
/// reach the SwiftUI-owned `AppState` from here directly, so the handler is
/// stashed on `DownloadManager.pendingBackgroundCompletion` and consumed when
/// `urlSessionDidFinishEvents(forBackgroundURLSession:)` fires.
final class BackgroundDownloadAppDelegate: NSObject, UIApplicationDelegate {
func application(
_ application: UIApplication,
handleEventsForBackgroundURLSession identifier: String,
completionHandler: @escaping () -> Void
) {
DownloadManager.pendingBackgroundCompletion = completionHandler
}
}
#endif