Is there a way to implement controls for background audio using ActivityKit like in the Apple Music application? I didn't found anything in your documentation about handling actions like this except deep links, but they're not suitable for this use case
ActivityKit
RSS for tagHelp people keep track of tasks and events that they care about with Live Activities on the Lock Screen, the Dynamic Island, and in StandBy.
Posts under ActivityKit tag
95 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Is it possible to load an image from remote in the Live Activity using ActivityKit? I tried various different methods, but none of them are working including:
AsyncImage
Pre-fetching the image in the App and passing that image to Activity as a Data through the context when starting the activity and converting Data back to the Image
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)
}
}
}
I have created a live activity that supports both light and dark mode, and are using the isLuminanceReduced environment variable to display the dark mode version on the always on display for the iPhone 14 Pro.
However it seems that this variable is not true when I switch to the Sleep Mode focus state. Even though the Lock Screen gets just as dark, it still shows the light mode version of the activity, which results text being very hard to read.
Any idea on what to do to display the dark mode version here? Or a way to have text that looks good in both light and dark screens?
Is there any way a live activity could be started from a shortcut? The example live activities (ordering a ride share, viewing sports scores etc) are good fits for shortcuts and live activities but I'm not able to start a live activity from a shortcut using the new app intents framework.
Is it possible to start a live activity from an app intent shortcut?
I have app that shows live activity and countdown till a date...
VStack {
Text("Countdown till You finish your homework")
Text(countdownTime, style: .timer)
}
After the time up, the live activity countup, the solution is to update the live activity via backgroundTask and this not always working, really apple sometimes fire the backgroundTask after hours.
Another solution is to set dismissalPolicy: .after(countdownTime), but once I did that the dynamic island not working and the activity status is ended after right calling...
await activity.end(using: state, dismissalPolicy: .after(countdownTime))
Can anyone help please, users feed back is why you we still see the old task on live activity. How come I can not update live activity? and how come if you set dismissalPolicy .after apple changes the activity status to ended and stop showing the dynamic island?
Hello,
i am implementing Live Activity and facing a problem setting custom color for widget background.
I have a dedicated catalogue of colors for WidgetExtension each having light/dark variant.
The problem is, however, that widget's view changes color variants (any/dark) according to system settings, but not system background & text of widget set via .activityBackgroundTint(_:) and activitySystemActionForegroundColor(_:)
Both widget background and system button texts remain in light variant no matter what system setting was when starting Live Activity.
Later, i was able to kinda force LA background color by checking color scheme in my widget view (yellow and brown for test purposes)
.activityBackgroundTint(colorScheme == .light ? Color.surface. : Color.brown)
this would force Live Activity background to have expected color from start.
BUT
when i later change appearance in system settings Live Activity behaves weirdly, as if it was caching previous color I provided.
I installed 16.2 beta in hope that it was fixed, but noticed this behaviour 👇
system in light mode: LA start, LA background is light
set system to dark: LA background light
set system to light: LA background dark ❗️
set system to dark: do not pull notification center, do not look at LA, instead immediately 👇
set system to light: LA background light
Is there any way around this? 🙏
I used ProgressView to display a countdown progress bar in a Live Activity. However, I found that since iOS 16.2, ProgressView(timerInterval:countsDown:) does not update properly in the following situations.
on Dynamic Island (either Expanded or CompactLeading/Trailing)
on the Locked Screen, after the display is turned off (isLuminanceReduced == true)
In these situations, the ProgressView for the countdown is always displayed at 100% and does not automatically update with the time. The problem only occurs in iOS 16.2. And it's confusing for users. Will it be fixed please?
I'm implementing a Timer in my app and I want the countdown to show up as a Live Activity. It works, but I get a very weird expanding effect on the Text view. The screenshots below show the issue, I can't tell if it's a bug or if I'm doing something wrong.
My goal is to shrink the live activity black area so that it's a smaller, more reasonable size. There's no reason for it to be as large as it is on the trailing side.
The Live Activity code (very basic):
} dynamicIsland: { context in
} compactTrailing: {
// Important bit is here
Text(Date(), style: .timer)
}
}
Which renders like this, with a lot of space after the timer:
Adding a background color shows the view is expanding:
Text(Date(), style: .timer)
.background(.red)
And if I replace the timer with a standard text view, then no issue:
Text("Hello")
.background(.red)
Getting out of live activities and showing a standard timer view, there is no expansion issue:
struct TestView: View {
var body: some View {
Text(Date(), style: .timer)
.background(.red)
}
}
So... I'm stumped. Any advice is appreciated.
Hi,
We have integrated LA in our app.
We have noticed that sometimes LA won't update although APNs is giving 200. To debug this we have enabled LA along side push notifications. Noticed getting push notifications on time but LA is not updating.
Not sure how to debug this? Is there anyone who has scaled LA successfully?
Thanks
I have found that the live activity push notification payload was changed from event -> events.
https://developer.apple.com/documentation/activitykit/updating-and-ending-your-live-activity-with-activitykit-push-notifications
Is it a mistake or it has been updated?
I want my live activity to show "in 3 min" text, and for it to be updated automatically every minute. I saw I could do: Text(date, style: .relative) but sadly it include seconds too: 3 min, 2 sec. Is there a way for me to remove the seconds?
There are many examples for this use case in the "Design dynamic Live Activities" session from WWDC23, especially at 11:35. How are they implementing that?
We are updating a Live Activity via push notifications quite frequently. As the documentation suggests, we are using NSSupportsLiveActivitiesFrequentUpdates for this case. We are sending all updates with apns-priority: 10.
Is it still possible that iOS throttles push-updates with this setting enabled?
For example we sent updates to APNS in this frequence:
2023-06-09T09:21:22.492224Z
2023-06-09T09:22:03.415876Z
2023-06-09T09:22:05.643268Z
2023-06-09T09:22:08.567353Z
2023-06-09T09:22:11.988442Z
2023-06-09T09:22:17.983494Z
2023-06-09T09:22:28.400757Z
2023-06-09T09:22:44.185622Z
2023-06-09T09:23:06.633058Z
2023-06-09T09:23:23.560052Z
2023-06-09T09:23:31.863625Z
2023-06-09T09:23:37.18351Z
2023-06-09T09:23:44.086319Z
2023-06-09T09:23:49.40655Z
2023-06-09T09:24:08.034848Z
2023-06-09T09:24:18.614194Z
2023-06-09T09:24:20.176428Z
2023-06-09T09:24:25.384654Z
2023-06-09T09:25:03.103147Z
2023-06-09T09:25:15.433726Z
2023-06-09T09:25:21.171693Z
2023-06-09T09:25:23.262028Z
2023-06-09T09:25:28.241116Z
2023-06-09T09:25:30.19816Z
2023-06-09T09:25:32.440543Z
2023-06-09T09:25:42.381815Z
2023-06-09T09:25:50.581656Z
2023-06-09T09:25:55.659846Z
2023-06-09T09:26:15.042667Z
2023-06-09T09:26:26.924626Z
2023-06-09T09:26:28.608762Z
2023-06-09T09:26:32.012874Z
2023-06-09T09:26:39.111211Z
2023-06-09T09:26:40.415326Z
2023-06-09T09:26:51.142985Z
2023-06-09T09:26:54.364073Z
2023-06-09T09:27:04.225692Z
2023-06-09T09:27:30.80347Z
2023-06-09T09:27:33.560981Z
2023-06-09T09:27:42.334313Z
2023-06-09T09:27:43.834646Z
All of those were sent successfully, but at some point the activity stopped updating. The activity continued for several hours after, but was never updated again.
What I checked so far:
From device logs we can see that there was no updated push-token
The sent content-state is correct
From these observations and considering the high-frequent updates, I suspect that there is still some throttling happening here.
Can anyone elaborate on this?
Thanks in advance.
I support Live Activities in my app, and am unable to dismiss Live Activities when the app gets closed from the background.
Currently, I subscribe to the willTerminateNotification notification in order to perform actions when the app gets terminated. This guys triggered when the app gets terminated in the foreground. However, if it gets terminated from the background, it does not get triggered and my Live Activity stays after the app gets closed. How can I prevent this from happening?
I have implemented Live Activity in my app but have encountered occasional errors when a user attempts to start a Live Activity. According to Apple's documentation, the error thrown should be an ActivityAuthorizationError but this has not been my experience in testing. I have been able to cast it as an NSError or an Error, but not as an ActivityAuthorizationError or a LocalizedError.
The code I've been using to start the Live Activity is pretty straightforward I think:
do {
let _ = try Activity.request(attributes: activityAttributes,
contentState: initialContentState) as Activity<MyActivityAttributes>
} catch {
print(error.localizedDescription)
// I would like to present an alert that provides a failure reason and recovery suggestion.
}
In my testing I can see the following error message:
Error Domain=com.apple.ActivityKit.ActivityInput Code=1 "(null)"
UserInfo={NSUnderlyingError=0x600003b17d20 {Error Domain=com.apple.ActivityKit.ActivityAuthorization Code=4 "(null)"}}
The error shown in the UserInfo seems to be an ActivityAuthorization error, but I can only cast it as an NSError or Error.
I would really like to provide the specific failure reason and recovery suggestion to users who experience a failure.
Has anyone else come across this? Are there suggestions on how to actually get access to the ActivityAuthorizationError type?
Thank you all.
live Activity’s stale date is not getting updated from remote notification. If it’s just from app, it’s working however from remote notification nothing is happening? What could be the possible reason?
I wanted to show count down timer in live activity. Since we can't use Timer in extensions, I used Text.init(timerInterval:pauseTime:countsDown:showsHours:) to show timer. But I need to show different text when the timer ends. How to achieve this behaviour?
How do you animate in live activities?
I've seen apps been able to update around 1 fps. For example with a character looping a dance animation.
How is this done?
I don't think you can call Activity.update() every second. Also it wouldn't run in the background all the time anyway?
Here's an example of Apple's own WWDC video with a bar animating
https://imgur.com/a/yywW7a8
According to apple
On devices that include an Always-On display, the system dims the
screen to preserve battery life and renders Live Activities on the
Lock Screen as if in Dark Mode. Use SwiftUI’s isLuminanceReduced
environment value to detect reduced luminance on devices with an
Always-On display and use images that look great for reduced
luminance.
But it seems to have no effect in live activities when displayed in the lock screen with AOD
@Environment(\.isLuminanceReduced) var isLuminanceReduced
Image("background1")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(height: 400)
.offset(y:-40)
.brightness(isLuminanceReduced ? -0.5 : 0)
Hello everyone,
I'm developing a new feature that allows the user to keep track of a background upload through live activities.
Im using the URLSessionTaskDelegate to keep track of the task progress and it works fine when the app is in foreground, but when the app goes to background, it stop after a few seconds. The upload still continues and Im able to receive updates on it's completion through the application(_ application: UIApplication, handleEventsForBackgroundURLSession but only through that.
Also when I put the app back to foreground it updates to the correct progress so this is only happening in background.
This is the URLSessionConfiguration I'm using:
let config = URLSessionConfiguration.background(withIdentifier: "\(uploadBackgroundTaskIdentifier)")
config.isDiscretionary = false
config.allowsCellularAccess = true
config.shouldUseExtendedBackgroundIdleMode = true
config.sessionSendsLaunchEvents = true
config.timeoutIntervalForResource = 28800
Does anyone knows how should I be able to keep track of the progress even when the app is in background?