I had a timer app, it played white noise after starting the timer. so my app is running in the background with background audio, and the timer is perfect for display with live activity.
However, when I test my code with a real device, I find calling await activity.update(using: contentState)
when app is running in the background does not work at all. the code executes, but the live activity won't get updated.
After some experiments, I find:
- if the app is running in the background with background location or Picture-in-picture mode, the app can update live activity when running in the background.
- If the app is running in the background with audio playing, it will work on simulator, but not on a real device.
I submit a feedback: FB11683922 (Can't update Live Activity from app with ActivityKit when app is running in the background with background audio playing.)
My code is like:
func startLiveActivity() {
// Prepare content state and attributes.
do {
self.activity = try Activity.request(attributes: activityAttributes, contentState: initialContentState)
// Play audio so app can keep running in the background.
try playAudio()
} catch (let error) {
print("Error requesting Live Activity \(error.localizedDescription).")
}
}
private func playAudio() throws {
try AVAudioSession.sharedInstance().setCategory(.playback, options: .mixWithOthers)
try AVAudioSession.sharedInstance().setActive(true)
if self.player == nil {
if let url = Bundle.main.url(forResource: "Forest", withExtension: "m4a") {
player = try AVAudioPlayer(contentsOf: url)
player?.numberOfLoops = -1
}
}
player?.stop()
player?.currentTime = 0
player?.play()
}
after the timer stops, the code will execute, but the live activity won't get updated.
func updateActivity(){
Task {
if let activity = self.activity {
// Prepare content state
await activity.update(using: contentState)
}
}
}