79 lines
2.4 KiB
Swift
79 lines
2.4 KiB
Swift
//
|
|
// ServicesMALiveActivityManager.swift
|
|
// Mobile Music Assistant
|
|
//
|
|
|
|
import ActivityKit
|
|
import Foundation
|
|
import MobileMAShared
|
|
import OSLog
|
|
|
|
private let logger = Logger(subsystem: "com.musicassistant.mobile", category: "LiveActivity")
|
|
|
|
/// Manages the Now Playing Live Activity lifecycle.
|
|
@Observable
|
|
final class MALiveActivityManager {
|
|
|
|
private var currentActivity: Activity<MusicActivityAttributes>?
|
|
|
|
init() {
|
|
// End any orphaned activities left over from previous sessions or format changes.
|
|
Task {
|
|
for orphan in Activity<MusicActivityAttributes>.activities {
|
|
await orphan.end(dismissalPolicy: .immediate)
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Public Interface
|
|
|
|
/// Start or update the Live Activity with current playback state.
|
|
func update(trackTitle: String, artistName: String, artworkData: Data?, isPlaying: Bool, playerName: String) {
|
|
let state = MusicActivityAttributes.ContentState(
|
|
trackTitle: trackTitle,
|
|
artistName: artistName,
|
|
artworkData: artworkData,
|
|
isPlaying: isPlaying,
|
|
playerName: playerName
|
|
)
|
|
|
|
if let activity = currentActivity {
|
|
Task {
|
|
await activity.update(ActivityContent(state: state, staleDate: nil))
|
|
logger.debug("Updated live activity: \(trackTitle)")
|
|
}
|
|
} else {
|
|
start(state: state)
|
|
}
|
|
}
|
|
|
|
/// End the Live Activity immediately.
|
|
func end() {
|
|
guard let activity = currentActivity else { return }
|
|
currentActivity = nil
|
|
Task {
|
|
await activity.end(dismissalPolicy: .immediate)
|
|
logger.debug("Ended live activity")
|
|
}
|
|
}
|
|
|
|
// MARK: - Private
|
|
|
|
private func start(state: MusicActivityAttributes.ContentState) {
|
|
guard ActivityAuthorizationInfo().areActivitiesEnabled else {
|
|
logger.info("Live Activities not enabled on this device")
|
|
return
|
|
}
|
|
do {
|
|
let activity = try Activity.request(
|
|
attributes: MusicActivityAttributes(),
|
|
content: ActivityContent(state: state, staleDate: nil)
|
|
)
|
|
currentActivity = activity
|
|
logger.info("Started live activity: \(state.trackTitle)")
|
|
} catch {
|
|
logger.error("Failed to start live activity: \(error.localizedDescription)")
|
|
}
|
|
}
|
|
}
|