ActivityKit

RSS for tag

Help 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

Post

Replies

Boosts

Views

Activity

Live Activity works perfectly on Simulator but fails on physical device: "No asset provider bundle ID provided"
Hello community, I am implementing a Live Activity for my existing App Store app. The Live Activity works perfectly on the iOS Simulator, but it completely fails to appear on the physical device's lock screen. When I call Activity.request, it succeeds and returns a valid Activity ID, but the physical device's console immediately outputs the following errors from liveactivitiesd: liveactivitiesd is not entitled to specify a scene target. Defaulting containingProcess target to liveactivitiesd No asset provider bundle ID provided I have spent days debugging this and have tried every known workaround. Here is the comprehensive list of what I have already verified and attempted: Environment: Xcode: 16.4 iOS Device: iPhone 13 mini, iOS 26.3.1 macOS: Sequoia 15.6 What I have verified/tried (to avoid duplicate suggestions): NSSupportsLiveActivities: It is set to YES in the main app's Info.plist. I also tried adding it to the Widget Extension's Info.plist just in case. App Icons: The main app has a valid AppIcon set in Assets.xcassets. The Primary App Icon Set Name in Build Settings is correctly set to AppIcon. Bundle IDs: They match perfectly (com.mycompany.app and com.mycompany.app.MyWidget). Version & Build Numbers: The main app and the Widget Extension have exactly the same Version and Build numbers. App Groups & Entitlements: Checked and perfectly synced between the main app and the extension. Dummy Widget: Since it's a Live-Activity-only extension, I added a standard static DummyWidget to the WidgetBundle to prevent the known iOS 17 bug where the system ignores extensions without home screen widgets. Memory/Sanitizers: Ensured Address Sanitizer and Zombie Objects are completely disabled in the Scheme to prevent the 30MB memory limit crash on the device. Nuclear Option: Completely deleted the Widget Extension target, wiped DerivedData, restarted the Mac and iPhone, and recreated the extension from scratch. Minimal UI Test: Replaced the widget's UI with a simple Text("Test") to rule out any SwiftUI rendering crashes. Device Settings: Verified that "Live Activities" is enabled under "Face ID & Passcode" settings on the physical iPhone. Despite all of this, the Simulator works flawlessy, while the device throws No asset provider bundle ID provided and shows nothing. Does anyone know what specific condition causes liveactivitiesd to fail to find the asset provider (the parent app) on a physical device for an existing app? Are there any undocumented provisioning profile quirks or obscure Build Settings I might be missing? Any insights would be deeply appreciated. Thank you!
3
0
358
Apr ’26
Live Activity Not Updating Frequently for Offline Music App (Lyrics Sync Issue)
Hi everyone, I’m currently implementing Live Activities in my music app to display real-time lyrics on the Lock Screen. The app works fully offline, so I’m not using push updates or push tokens. Instead, I’m updating the Live Activity locally as each new line of lyrics is played (essentially near real-time updates synced with the song). However, I’m running into an issue where the Live Activity UI is not updating reliably or frequently enough. Even though I’m calling the update method for each lyric line, the changes are either delayed or not reflected at all. Here’s some additional context: • The app runs fine in the background (verified via battery usage and playback behavior) • Live Activity is successfully created and initially displayed • Updates are triggered locally (no push notifications involved) • Updates are happening quite frequently (per lyric line) • No crashes or errors are observed My questions: 1. Is there a system-imposed throttling limit on how frequently Live Activities can be updated locally? 2. Are there recommended update intervals for smooth UI updates (e.g., for use cases like lyrics or timers)? 3. Does Live Activity deprioritize updates for offline apps or background execution? 4. Are there any additional configurations or capabilities required to ensure consistent updates? 5. Is using something like AsyncStream or other concurrency patterns helpful in this case? 6. Are there any undocumented limitations or best practices for high-frequency updates? 7. Is there any private or internal API used by Apple apps (like Music) that allows smoother real-time updates? My goal is to achieve smooth, near real-time lyric updates similar to Apple Music’s Now Playing experience. Any guidance, best practices, or clarification would be greatly appreciated. Thanks in advance!
0
0
267
Apr ’26
Live Activity Silent Rendering Failure- Any Way to Detect Crash / Failure State?
Hi Apple Team, We are facing an issue with Live Activities where the UI intermittently fails to render and shows a loader or blank state. After extensive debugging, we’ve identified that the failure happens during the rendering phase inside the system process (WidgetKit / liveactivitiesd), but there are no actionable signals exposed to the app. Problem: Live Activity launches successfully After a few updates or under certain UI conditions, it: stops rendering shows a loader / blank UI sometimes disappears No crash logs are generated No MetricKit diagnostics available for the extension Console logs show: Invalid frame dimension (negative or non-finite) Archive was nil. LiveActivity will be empty Sometimes because of memory pressure too The extension process appears to terminate silently Challenge Currently, there is no way to detect from the app side that: the Live Activity has failed to render the extension process has crashed/terminated the UI is no longer being updated Questions Is there any callback, delegate, or lifecycle hook that notifies when: a Live Activity rendering fails the extension process crashes or is terminated by the system? Is there any recommended way to detect a “broken” Live Activity state (e.g., stuck loader / non-updating UI)? Are there any diagnostic APIs or logs we can rely on in production to identify such failures? Is this considered expected behavior under certain system constraints (e.g., memory/rendering limits), and if so, are there guidelines to proactively detect or mitigate it? Goal We want to: proactively detect Live Activity failure log it for monitoring optionally fallback or recover gracefully Additional context: We fixed all the issues and the live activity is pretty stable. But asking for methods to track & fix such cases.
0
1
387
Apr ’26
Live Activity Stops Updating After 30 Seconds in Background During Audio Playback
Hi I developed a music app that plays offline audio and displays lyrics using Live Activities. According to ActivityKit documentation, Live Activities can be updated from the background. However, in my case, updates stop after ~30 seconds when the app goes to the background or the device is locked. Important points: The app continues running in the background (audio playback works fine using AVAudioSession with .playback) Background code execution is working as expected Only the Live Activity stops updating I am not using push updates since this is an offline app. Is there any limitation or requirement for updating Live Activities continuously in the background during audio playback? Audio Session Configuration let session = AVAudioSession.sharedInstance() try session.setCategory( .playback, mode: .default, options: [.mixWithOthers] // ✅ DO NOT interrupt other audio ) try session.setActive(true) print("✅ [AudioSession] Activated with mixWithOthers") } catch { print("❌ [AudioSession] Error: \(error)") } Live Activity Update Methods guard let activity = getLiveActivity(for: recordID) else{ print("⚠️ No Live Activity found for recordID: \(recordID)") return } guard activity.activityState == .active else { print("⚠️ Activity is not active") return } Task { let content = ActivityContent( state: state, staleDate: Date().addingTimeInterval(60 * 60 * 12), relevanceScore: 1.0 ) await activity.update(content) print("✅ Live Activity updated with ActivityContent") } }
0
0
405
Apr ’26
Minimum achievable latency for ending a Live Activity after app force-kill via APNs push-to-end
Context I'm building a study-timer feature for an iOS app (Flutter + native ActivityKit) that displays a Live Activity on the Lock Screen / Dynamic Island while a session is running. When the user force-quits the app by swiping it up from the App Switcher, I want the Live Activity to disappear as quickly as possible. I have already confirmed (from on-device testing and Apple Developer Forums thread 732418) that: applicationWillTerminate is not called on swipe-up force-kill, only on OS-initiated termination or crash. So synchronous Activity.end(...) from the app itself is not a solution for the force-kill path. Shortening staleDate does not visually dismiss the Live Activity once the app process is gone — the Widget Extension keeps rendering the last fresh snapshot and there is no body-reevaluation trigger on the stale transition post-app-death. (I implemented and verified this, then rolled it back.) The only Apple-official reliable mechanism is APNs push-to-end (Activity.request(pushType: .token) + server sends event: end via APNs). Current architecture I have APNs push-to-end working end-to-end. Structure: Client: Activity.request(pushType: .token), subscribe to Activity.pushTokenUpdates, forward each new token to the backend. Backend: On every client heartbeat, upsert (user_id, la_apns_token, la_activity_id, last_heartbeat) into Postgres. A separate scheduler polls for rows whose last_heartbeat < now() - grace_ttl and sends APNs event: end to the stored token. Parameters I am currently running with: Parameter Value Client heartbeat interval 60 s Orphan grace TTL (server) 135 s (heartbeat × 2.25, to absorb network jitter) Scheduler poll interval 30 s The observation End-to-end latency from "user force-kills the app" to "Live Activity disappears from Lock Screen" is: Worst case: 60 + 135 + 30 = ~225 s (~3.75 min) Typical: ~3 min (as consistently measured on iOS 26.4.1, iPhone 17 Pro Max) Theoretical minimum (if the kill happens exactly at a heartbeat boundary): ~135 s Users perceive 3 minutes as broken — the timer clearly stopped (no ticking), but the Live Activity "ghost" is still visible on the Lock Screen. My question Is there any Apple-supported mechanism to reliably tear down a Live Activity faster than ~2 minutes after the owning app's process is gone, given that applicationWillTerminate does not fire on swipe-kill? Specifically: Is there any practical lower bound below ~60 s for this scenario using the current ActivityKit + APNs model, assuming we are not willing to spam heartbeats every few seconds? I can push heartbeat to 20–30 s, but the server cost grows linearly with active sessions. Does BGAppRefreshTask / BGProcessingTask have any documented lifecycle hook that fires on user-initiated swipe-kill specifically, so that I could do a "last-heartbeat flush" just before the process dies? My understanding is that background tasks are scheduled for later and do not fire synchronously at termination. Is there any signal from APNs/ActivityKit to my server (e.g. a feedback-service-like mechanism) that indicates "this Live Activity's owning app was force-killed", which would let the server short-circuit the heartbeat-based orphan detection? Are there any new APIs in iOS 18.x or the upcoming release that address this specific force-kill → LA-dismissal latency? I could not find anything in the 18.x release notes, but I may have missed it. What I am NOT asking I am not asking how to implement APNs push-to-end (that works). I am not asking about applicationWillTerminate (I already confirmed it does not fire on swipe-kill). I am not asking about shortening staleDate as a visual workaround (I already verified it does not trigger body reevaluation post-kill). Environment iOS 26.4.1 (also reproducible on 18.x devices I have on hand) iPhone 17 Pro Max, iPhone 15 Pro, iPad Air 11-inch (M3) Xcode 26.x Activity.request(pushType: .token) with ActivityContent + custom stalenessInterval = 120s APNs HTTP/2 via token auth (.p8), targeting api.push.apple.com in production apns-push-type: liveactivity, apns-priority: 10, payload includes event: end What I have tried (for the record, to avoid "did you try" responses) applicationWillTerminate with DispatchSemaphore 3.5 s sync wait + dismissalPolicy: .immediate — works only for OS-terminate, not swipe-kill. stalenessInterval = 30s + 15 s refresh cadence + override to 5 s on AppLifecycleState.paused — verified not to dismiss the LA after app death. Cold-start reconciliation via Activity<...>.activities on next app launch — works, but that only helps if the user relaunches. Current APNs push-to-end with 60 s / 135 s / 30 s configuration — works, but latency is the complaint. Any guidance, even "no, ~2 minutes is the floor by design" with a pointer to the relevant doc, would be very helpful. Thank you.
0
0
234
Apr ’26
Live Activity / Dynamic Island countdown responds to manual device clock changes, while app timer and shielding remain correct
Our app runs offline-first focus sessions using FamilyControls / ManagedSettings shielding and DeviceActivity monitoring. The in-app session timer is protected against wall-clock manipulation by using monotonic elapsed time, and the shield remains active correctly when the user manually changes the iPhone clock. However, the Live Activity and Dynamic Island countdown appear to use the device's wall clock for their timer rendering. If the user changes the device time from Settings during an active session, the Live Activity / Dynamic Island countdown immediately jumps forward or backwards, even though the underlying session has not changed. Is there a recommended ActivityKit approach for rendering a Live Activity / Dynamic Island countdown that is resistant to manual device clock changes? If not, is this an expected limitation of Live Activity timer rendering? And is there any supported way for the host app or widget extension to detect wall-clock manipulation so the Live Activity can be corrected, dismissed, or replaced with a safer non-countdown state?
0
0
243
Apr ’26
apply .activityBackgroundTint modifier in smartstack
On iOS 26, when using .activityBackgroundTint modifiers to change the background color in the Activity Kit, the changes do not appear to apply correctly in Smart Stack. While the color changes as expected, the background is rendered as simply transparent without a glass effect which reduces readability. The glass effect is applied only when activityBackgroundTint is not used.
0
0
326
May ’26
Live Activities Permissions
I have a live activity and even after a couple of times that it has shown on my lock screen it keeps prompting the user to tap on Don't Allow or Allow. Can someone help me understand why this is happening? I would like my users to only hit Allow once and not be prompted again, otherwise they would not be registered for updates, since update token only generates after selecting Allow.
2
0
397
2w
Live Activity Start and Update Token Invalidation
Hi everyone, I have a question about Live Activity start tokens and update tokens. After reading the documentation, it is still not very clear to me how often these tokens are invalidated, and whether their expiration is time-based or event-based. My current understanding is that the update token is generated when the Live Activity starts, and that it becomes invalid when the activity ends or is dismissed by the user. What I am not clear on is whether the update token can also become invalid at any point while the Live Activity is still active. I have a similar question about the start token. I have noticed that it is generated on the initial app launch, but I have also seen it get regenerated at what seems like random times. I would like to better understand what events or conditions cause a new start token to be issued. Is there any official guidance on the lifecycle of these tokens, specifically: whether they expire based on time, whether they are only invalidated by specific events, and what conditions trigger regeneration of the start token or update token? Any clarification would be appreciated. Thanks.
1
0
233
3w
Live Activities/Widget Extension Isolation
Our application currently supports Live Activities. We’re working on adding a new Widget and are weighing some architectural decisions regarding whether we should add it to the same extension target that our Live Activity lives in or create a new extension that would expose it and other widgets we plan to create in the future. In the Add Support for Live Activities documentation, it suggests adding Live Activity code to the existing widget extension to facilitate code reuse. Beyond code sharing, we’re trying to determine if there are downsides to isolating new Widget(s) into their own extension. Specifically, we are concerned about process isolation and how a failure/crash in one might impact the other. Assuming they did live in the same extension, we’re hoping to better understand some of the finer details as presented by the following questions: If a Widget (e.g., via the TimelineProvider) causes the extension process to crash, what is the guaranteed behavior for a currently running Live Activity? Is the relaunch and restoration of a Live Activity after an extension crash guaranteed, or is it best-effort? Is there a distinction in crash isolation between a TimelineProvider failure and a View rendering crash? Are there any known scenarios where a Widget crash could cause a Live Activity to be permanently dropped? Does keeping them in the same extension affect the memory budget, or does each 'instance' receive its own allocation? In short: we're looking to ensure that an issue with a Widget doesn't inadvertently affect a Live Activity (or vice-versa) when they live in the same WidgetsBundle within the same extension and are seeking guidance on whether it makes sense to keep them together or continue down the path of separate extensions in the interest of process safety. Any pointers to other documentation or known behavior would be greatly appreciated!
0
2
149
2w
Issue Getting Live Activity Push to Start and Update Tokens
I'm adding live activities to my app and I'm trying to use push notifications to fully remotely start them and end them. The pushToStartTokenUpdates sequence gives start tokens exactly as expected, and triggers even when the app is fully terminated when a new live activity starts. However, the pushTokenUpdates sequence is far less predictable and seems to never trigger when the app is fully terminated. Even when the app is just backgrounded, it's still finicky. I send the "input-push-token": 1 as part of the aps payload too to begin the live activity, but that seems to have little to no effect. Is there any way to ensure that we can receive a push token specifically to update the live activity after it starts? It seems to me that if a live activity can be started via push even when the app is fully terminated, and live activities are meant to reflect active information, then the mechanism to update it via a new token should also be able to work when the app is terminated. Both sequences are subscribed to within the AppDelegate upon initial app launch. This is what my code looks like at the moment: func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { Task { for await newToken in Activity<WidgetAttributes>.pushToStartTokenUpdates { let tokenString = newToken.map{ String(format: "%02x", $0) }.joined() // send to server } } Task { for await activity in Activity<WidgetAttributes>.activityUpdates { Task { for await token in activity.pushTokenUpdates { let tokenString = token.map { String(format: "%02x", $0) }.joined() // send to server } } } } } } Thanks in advance for any insights!
1
0
156
2w
LiveActivity via Push-To-Start and Update token questions.
We are implementing starting an activity via Push-To-Start. For the most part it works great, however we have run into a few edge cases. Currently, we send the "start activity" push notification and it creates the Activity as expected. If the app doesn't send an update token w/in a configured time, we assume the activity didn't start and try to start the activity again. Occasionally we get into a situation where there have been multiple activities started, but it should really only be one. Here is my theory: We store an auth token in the keychain for all REST endpoints if the phone has been restarted and not unlocked, the app doesn't have access to the auth token and fails to send the update token to our backend. Are there any best practices on how to manage PTS and UPDATE tokens? (updating these w/o authentication seems problematic)
1
0
291
1w
Do interactive LiveActivityIntent buttons keep the Lock Screen awake like Now Playing controls?
I am developing an iOS app using ActivityKit Live Activities with interactive buttons based on LiveActivityIntent. The implementation works correctly: LiveActivityIntent.perform() executes correctly. The Live Activity updates visually. MediaPlayer actions are triggered successfully. The app does not open when tapping the buttons. Repeated taps correctly update the Live Activity state. However, I observed a behavior difference on the Lock Screen: Now Playing controls keep the Lock Screen awake while interacting repeatedly. Apple Stopwatch/Timer controls also keep the Lock Screen awake while interacting. My app’s Live Activity fades to black after around 5–7 seconds even while the user continues tapping the Live Activity buttons. I also tested a third-party timer app with Live Activity buttons and observed the same fade-to-black behavior. I additionally tested: repeated Activity.update(...) calls after each tap; visual state updates after every interaction; multiple consecutive interaction updates. None of these prevented the Lock Screen from dimming/fading to black. So my question is: Is this expected behavior for third-party Live Activities using LiveActivityIntent? Or is there any recommended way to keep the Lock Screen interaction session active while the user is continuously interacting with Live Activity buttons? I am especially interested from an accessibility perspective, because short interaction windows can make repeated Lock Screen interactions more difficult for users with motor impairments or slower interaction patterns.
0
0
140
2w
Query regarding Live Activity push notification delivery and throttling behavior
We are using Live Activities in our iOS app to show real-time flight information on the Lock Screen and Dynamic Island. Our implementation currently works as follows: The Live Activity is created using the push-to-start token. After the Live Activity is started, our backend receives and uses the Live Activity update token to send updates to the Live Activity through APNs. The Live Activity content is updated through push notifications from our backend. These updates include flight status changes such as check-in status, boarding status, gate changes, delay updates, arrival status, and other journey-related states. We are observing an issue where some Live Activity state updates are not reflected on the device. From our backend logs, the APNs request is successfully sent, but in some cases the update does not appear to be received by the device, and the Live Activity remains in an older state. We understand from Apple documentation and platform behavior that Live Activity push updates may be subject to system-level throttling or delivery limitations. We would like to confirm the expected behavior and understand the recommended approach. Could you please help clarify the following? Are Live Activity update pushes subject to throttling by iOS/APNs even when the backend sends the update successfully? If APNs accepts the request successfully, is there still a possibility that the update may not be delivered to the device or may not update the Live Activity because of system-level throttling, device state, power conditions, network conditions, or Live Activity limits?
1
0
107
1w
Boarding pass Live Activity ignores localized destinationCityName — "Willkommen bei Munich" on de_DE device
Platform: iOS 26.5 · PassKit (semantic boarding pass) Summary When a .pkpass boarding pass uses the iOS 26 upgraded semantic format (preferredStyleSchemes: ["semanticBoardingPass", "boardingPass"]) for a real, scheduled flight that Apple's live flight data feed recognizes, the Wallet Live Activity (Lock Screen, Dynamic Island, and Wallet card "Welcome to …" copy) renders the destination city name in English, regardless of the value supplied in semantics.destinationCityName or the device's locale. On a German-locale iPhone, a flight arriving at MUC produces the grammatically broken string "Willkommen bei Munich" — German system-supplied prefix concatenated with the English city noun from Apple's flight data, instead of the expected "Willkommen in München". Steps to reproduce Build a .pkpass for any real, currently-scheduled flight whose destination city has a German-language variant (e.g. SK2657 CPH→MUC, 4Y1261 HER→MUC). Populate semantics with full iOS 26 fields including: "destinationAirportCode": "MUC", "destinationAirportName": "München", "destinationCityName": "München", "destinationLocationDescription": "Flughafen München Franz Josef Strauß" Install on an iPhone running iOS 26.1+ with Language: Deutsch, Region: Deutschland. Open the pass within Wallet's live-activity window. Expected: "Willkommen in München" Actual: "Willkommen bei Munich" What I believe is happening Apple's live flight data feed overrides the destinationCityName semantic tag with an English-only value sourced from the feed (presumably IATA / OAG). The iOS 26.1 liveDataConfiguration.excludedSemantics allow-list does not include destinationCityName or destinationAirportName, so there is currently no developer-side mechanism to either: submit a localized destination city, or opt out of the override while keeping live updates active. The PassKit destinationCityName schema is typed as a plain localizable string (single value), with no translations variant comparable to what some third-party pass APIs expose. The "localizable" annotation in the docs is misleading for this field, because pass.strings lookups are not applied to semantic values once the live flight feed supplies them. What I'd like to know Is this the intended behavior, or is destinationCityName missing from the documented excludedSemantics allow-list by omission rather than design? Is there a supported way for an airline (or a developer issuing passes on an airline's behalf) to ship localized destination city names that survive the live-data merge? If neither (1) nor (2): is there an intent to either localize Apple's flight-data city tokens by device locale, or expand excludedSemantics to cover destination/departure city + airport names in a future iOS 26.x release?
0
0
38
20h
Live Activity works perfectly on Simulator but fails on physical device: "No asset provider bundle ID provided"
Hello community, I am implementing a Live Activity for my existing App Store app. The Live Activity works perfectly on the iOS Simulator, but it completely fails to appear on the physical device's lock screen. When I call Activity.request, it succeeds and returns a valid Activity ID, but the physical device's console immediately outputs the following errors from liveactivitiesd: liveactivitiesd is not entitled to specify a scene target. Defaulting containingProcess target to liveactivitiesd No asset provider bundle ID provided I have spent days debugging this and have tried every known workaround. Here is the comprehensive list of what I have already verified and attempted: Environment: Xcode: 16.4 iOS Device: iPhone 13 mini, iOS 26.3.1 macOS: Sequoia 15.6 What I have verified/tried (to avoid duplicate suggestions): NSSupportsLiveActivities: It is set to YES in the main app's Info.plist. I also tried adding it to the Widget Extension's Info.plist just in case. App Icons: The main app has a valid AppIcon set in Assets.xcassets. The Primary App Icon Set Name in Build Settings is correctly set to AppIcon. Bundle IDs: They match perfectly (com.mycompany.app and com.mycompany.app.MyWidget). Version & Build Numbers: The main app and the Widget Extension have exactly the same Version and Build numbers. App Groups & Entitlements: Checked and perfectly synced between the main app and the extension. Dummy Widget: Since it's a Live-Activity-only extension, I added a standard static DummyWidget to the WidgetBundle to prevent the known iOS 17 bug where the system ignores extensions without home screen widgets. Memory/Sanitizers: Ensured Address Sanitizer and Zombie Objects are completely disabled in the Scheme to prevent the 30MB memory limit crash on the device. Nuclear Option: Completely deleted the Widget Extension target, wiped DerivedData, restarted the Mac and iPhone, and recreated the extension from scratch. Minimal UI Test: Replaced the widget's UI with a simple Text("Test") to rule out any SwiftUI rendering crashes. Device Settings: Verified that "Live Activities" is enabled under "Face ID & Passcode" settings on the physical iPhone. Despite all of this, the Simulator works flawlessy, while the device throws No asset provider bundle ID provided and shows nothing. Does anyone know what specific condition causes liveactivitiesd to fail to find the asset provider (the parent app) on a physical device for an existing app? Are there any undocumented provisioning profile quirks or obscure Build Settings I might be missing? Any insights would be deeply appreciated. Thank you!
Replies
3
Boosts
0
Views
358
Activity
Apr ’26
Live Activity Not Updating Frequently for Offline Music App (Lyrics Sync Issue)
Hi everyone, I’m currently implementing Live Activities in my music app to display real-time lyrics on the Lock Screen. The app works fully offline, so I’m not using push updates or push tokens. Instead, I’m updating the Live Activity locally as each new line of lyrics is played (essentially near real-time updates synced with the song). However, I’m running into an issue where the Live Activity UI is not updating reliably or frequently enough. Even though I’m calling the update method for each lyric line, the changes are either delayed or not reflected at all. Here’s some additional context: • The app runs fine in the background (verified via battery usage and playback behavior) • Live Activity is successfully created and initially displayed • Updates are triggered locally (no push notifications involved) • Updates are happening quite frequently (per lyric line) • No crashes or errors are observed My questions: 1. Is there a system-imposed throttling limit on how frequently Live Activities can be updated locally? 2. Are there recommended update intervals for smooth UI updates (e.g., for use cases like lyrics or timers)? 3. Does Live Activity deprioritize updates for offline apps or background execution? 4. Are there any additional configurations or capabilities required to ensure consistent updates? 5. Is using something like AsyncStream or other concurrency patterns helpful in this case? 6. Are there any undocumented limitations or best practices for high-frequency updates? 7. Is there any private or internal API used by Apple apps (like Music) that allows smoother real-time updates? My goal is to achieve smooth, near real-time lyric updates similar to Apple Music’s Now Playing experience. Any guidance, best practices, or clarification would be greatly appreciated. Thanks in advance!
Replies
0
Boosts
0
Views
267
Activity
Apr ’26
Live Activity Silent Rendering Failure- Any Way to Detect Crash / Failure State?
Hi Apple Team, We are facing an issue with Live Activities where the UI intermittently fails to render and shows a loader or blank state. After extensive debugging, we’ve identified that the failure happens during the rendering phase inside the system process (WidgetKit / liveactivitiesd), but there are no actionable signals exposed to the app. Problem: Live Activity launches successfully After a few updates or under certain UI conditions, it: stops rendering shows a loader / blank UI sometimes disappears No crash logs are generated No MetricKit diagnostics available for the extension Console logs show: Invalid frame dimension (negative or non-finite) Archive was nil. LiveActivity will be empty Sometimes because of memory pressure too The extension process appears to terminate silently Challenge Currently, there is no way to detect from the app side that: the Live Activity has failed to render the extension process has crashed/terminated the UI is no longer being updated Questions Is there any callback, delegate, or lifecycle hook that notifies when: a Live Activity rendering fails the extension process crashes or is terminated by the system? Is there any recommended way to detect a “broken” Live Activity state (e.g., stuck loader / non-updating UI)? Are there any diagnostic APIs or logs we can rely on in production to identify such failures? Is this considered expected behavior under certain system constraints (e.g., memory/rendering limits), and if so, are there guidelines to proactively detect or mitigate it? Goal We want to: proactively detect Live Activity failure log it for monitoring optionally fallback or recover gracefully Additional context: We fixed all the issues and the live activity is pretty stable. But asking for methods to track & fix such cases.
Replies
0
Boosts
1
Views
387
Activity
Apr ’26
Live Activity Stops Updating After 30 Seconds in Background During Audio Playback
Hi I developed a music app that plays offline audio and displays lyrics using Live Activities. According to ActivityKit documentation, Live Activities can be updated from the background. However, in my case, updates stop after ~30 seconds when the app goes to the background or the device is locked. Important points: The app continues running in the background (audio playback works fine using AVAudioSession with .playback) Background code execution is working as expected Only the Live Activity stops updating I am not using push updates since this is an offline app. Is there any limitation or requirement for updating Live Activities continuously in the background during audio playback? Audio Session Configuration let session = AVAudioSession.sharedInstance() try session.setCategory( .playback, mode: .default, options: [.mixWithOthers] // ✅ DO NOT interrupt other audio ) try session.setActive(true) print("✅ [AudioSession] Activated with mixWithOthers") } catch { print("❌ [AudioSession] Error: \(error)") } Live Activity Update Methods guard let activity = getLiveActivity(for: recordID) else{ print("⚠️ No Live Activity found for recordID: \(recordID)") return } guard activity.activityState == .active else { print("⚠️ Activity is not active") return } Task { let content = ActivityContent( state: state, staleDate: Date().addingTimeInterval(60 * 60 * 12), relevanceScore: 1.0 ) await activity.update(content) print("✅ Live Activity updated with ActivityContent") } }
Replies
0
Boosts
0
Views
405
Activity
Apr ’26
Minimum achievable latency for ending a Live Activity after app force-kill via APNs push-to-end
Context I'm building a study-timer feature for an iOS app (Flutter + native ActivityKit) that displays a Live Activity on the Lock Screen / Dynamic Island while a session is running. When the user force-quits the app by swiping it up from the App Switcher, I want the Live Activity to disappear as quickly as possible. I have already confirmed (from on-device testing and Apple Developer Forums thread 732418) that: applicationWillTerminate is not called on swipe-up force-kill, only on OS-initiated termination or crash. So synchronous Activity.end(...) from the app itself is not a solution for the force-kill path. Shortening staleDate does not visually dismiss the Live Activity once the app process is gone — the Widget Extension keeps rendering the last fresh snapshot and there is no body-reevaluation trigger on the stale transition post-app-death. (I implemented and verified this, then rolled it back.) The only Apple-official reliable mechanism is APNs push-to-end (Activity.request(pushType: .token) + server sends event: end via APNs). Current architecture I have APNs push-to-end working end-to-end. Structure: Client: Activity.request(pushType: .token), subscribe to Activity.pushTokenUpdates, forward each new token to the backend. Backend: On every client heartbeat, upsert (user_id, la_apns_token, la_activity_id, last_heartbeat) into Postgres. A separate scheduler polls for rows whose last_heartbeat < now() - grace_ttl and sends APNs event: end to the stored token. Parameters I am currently running with: Parameter Value Client heartbeat interval 60 s Orphan grace TTL (server) 135 s (heartbeat × 2.25, to absorb network jitter) Scheduler poll interval 30 s The observation End-to-end latency from "user force-kills the app" to "Live Activity disappears from Lock Screen" is: Worst case: 60 + 135 + 30 = ~225 s (~3.75 min) Typical: ~3 min (as consistently measured on iOS 26.4.1, iPhone 17 Pro Max) Theoretical minimum (if the kill happens exactly at a heartbeat boundary): ~135 s Users perceive 3 minutes as broken — the timer clearly stopped (no ticking), but the Live Activity "ghost" is still visible on the Lock Screen. My question Is there any Apple-supported mechanism to reliably tear down a Live Activity faster than ~2 minutes after the owning app's process is gone, given that applicationWillTerminate does not fire on swipe-kill? Specifically: Is there any practical lower bound below ~60 s for this scenario using the current ActivityKit + APNs model, assuming we are not willing to spam heartbeats every few seconds? I can push heartbeat to 20–30 s, but the server cost grows linearly with active sessions. Does BGAppRefreshTask / BGProcessingTask have any documented lifecycle hook that fires on user-initiated swipe-kill specifically, so that I could do a "last-heartbeat flush" just before the process dies? My understanding is that background tasks are scheduled for later and do not fire synchronously at termination. Is there any signal from APNs/ActivityKit to my server (e.g. a feedback-service-like mechanism) that indicates "this Live Activity's owning app was force-killed", which would let the server short-circuit the heartbeat-based orphan detection? Are there any new APIs in iOS 18.x or the upcoming release that address this specific force-kill → LA-dismissal latency? I could not find anything in the 18.x release notes, but I may have missed it. What I am NOT asking I am not asking how to implement APNs push-to-end (that works). I am not asking about applicationWillTerminate (I already confirmed it does not fire on swipe-kill). I am not asking about shortening staleDate as a visual workaround (I already verified it does not trigger body reevaluation post-kill). Environment iOS 26.4.1 (also reproducible on 18.x devices I have on hand) iPhone 17 Pro Max, iPhone 15 Pro, iPad Air 11-inch (M3) Xcode 26.x Activity.request(pushType: .token) with ActivityContent + custom stalenessInterval = 120s APNs HTTP/2 via token auth (.p8), targeting api.push.apple.com in production apns-push-type: liveactivity, apns-priority: 10, payload includes event: end What I have tried (for the record, to avoid "did you try" responses) applicationWillTerminate with DispatchSemaphore 3.5 s sync wait + dismissalPolicy: .immediate — works only for OS-terminate, not swipe-kill. stalenessInterval = 30s + 15 s refresh cadence + override to 5 s on AppLifecycleState.paused — verified not to dismiss the LA after app death. Cold-start reconciliation via Activity<...>.activities on next app launch — works, but that only helps if the user relaunches. Current APNs push-to-end with 60 s / 135 s / 30 s configuration — works, but latency is the complaint. Any guidance, even "no, ~2 minutes is the floor by design" with a pointer to the relevant doc, would be very helpful. Thank you.
Replies
0
Boosts
0
Views
234
Activity
Apr ’26
Live Activity / Dynamic Island countdown responds to manual device clock changes, while app timer and shielding remain correct
Our app runs offline-first focus sessions using FamilyControls / ManagedSettings shielding and DeviceActivity monitoring. The in-app session timer is protected against wall-clock manipulation by using monotonic elapsed time, and the shield remains active correctly when the user manually changes the iPhone clock. However, the Live Activity and Dynamic Island countdown appear to use the device's wall clock for their timer rendering. If the user changes the device time from Settings during an active session, the Live Activity / Dynamic Island countdown immediately jumps forward or backwards, even though the underlying session has not changed. Is there a recommended ActivityKit approach for rendering a Live Activity / Dynamic Island countdown that is resistant to manual device clock changes? If not, is this an expected limitation of Live Activity timer rendering? And is there any supported way for the host app or widget extension to detect wall-clock manipulation so the Live Activity can be corrected, dismissed, or replaced with a safer non-countdown state?
Replies
0
Boosts
0
Views
243
Activity
Apr ’26
apply .activityBackgroundTint modifier in smartstack
On iOS 26, when using .activityBackgroundTint modifiers to change the background color in the Activity Kit, the changes do not appear to apply correctly in Smart Stack. While the color changes as expected, the background is rendered as simply transparent without a glass effect which reduces readability. The glass effect is applied only when activityBackgroundTint is not used.
Replies
0
Boosts
0
Views
326
Activity
May ’26
Live Activities Permissions
I have a live activity and even after a couple of times that it has shown on my lock screen it keeps prompting the user to tap on Don't Allow or Allow. Can someone help me understand why this is happening? I would like my users to only hit Allow once and not be prompted again, otherwise they would not be registered for updates, since update token only generates after selecting Allow.
Replies
2
Boosts
0
Views
397
Activity
2w
Live Activity Start and Update Token Invalidation
Hi everyone, I have a question about Live Activity start tokens and update tokens. After reading the documentation, it is still not very clear to me how often these tokens are invalidated, and whether their expiration is time-based or event-based. My current understanding is that the update token is generated when the Live Activity starts, and that it becomes invalid when the activity ends or is dismissed by the user. What I am not clear on is whether the update token can also become invalid at any point while the Live Activity is still active. I have a similar question about the start token. I have noticed that it is generated on the initial app launch, but I have also seen it get regenerated at what seems like random times. I would like to better understand what events or conditions cause a new start token to be issued. Is there any official guidance on the lifecycle of these tokens, specifically: whether they expire based on time, whether they are only invalidated by specific events, and what conditions trigger regeneration of the start token or update token? Any clarification would be appreciated. Thanks.
Replies
1
Boosts
0
Views
233
Activity
3w
Live Activities/Widget Extension Isolation
Our application currently supports Live Activities. We’re working on adding a new Widget and are weighing some architectural decisions regarding whether we should add it to the same extension target that our Live Activity lives in or create a new extension that would expose it and other widgets we plan to create in the future. In the Add Support for Live Activities documentation, it suggests adding Live Activity code to the existing widget extension to facilitate code reuse. Beyond code sharing, we’re trying to determine if there are downsides to isolating new Widget(s) into their own extension. Specifically, we are concerned about process isolation and how a failure/crash in one might impact the other. Assuming they did live in the same extension, we’re hoping to better understand some of the finer details as presented by the following questions: If a Widget (e.g., via the TimelineProvider) causes the extension process to crash, what is the guaranteed behavior for a currently running Live Activity? Is the relaunch and restoration of a Live Activity after an extension crash guaranteed, or is it best-effort? Is there a distinction in crash isolation between a TimelineProvider failure and a View rendering crash? Are there any known scenarios where a Widget crash could cause a Live Activity to be permanently dropped? Does keeping them in the same extension affect the memory budget, or does each 'instance' receive its own allocation? In short: we're looking to ensure that an issue with a Widget doesn't inadvertently affect a Live Activity (or vice-versa) when they live in the same WidgetsBundle within the same extension and are seeking guidance on whether it makes sense to keep them together or continue down the path of separate extensions in the interest of process safety. Any pointers to other documentation or known behavior would be greatly appreciated!
Replies
0
Boosts
2
Views
149
Activity
2w
Issue Getting Live Activity Push to Start and Update Tokens
I'm adding live activities to my app and I'm trying to use push notifications to fully remotely start them and end them. The pushToStartTokenUpdates sequence gives start tokens exactly as expected, and triggers even when the app is fully terminated when a new live activity starts. However, the pushTokenUpdates sequence is far less predictable and seems to never trigger when the app is fully terminated. Even when the app is just backgrounded, it's still finicky. I send the "input-push-token": 1 as part of the aps payload too to begin the live activity, but that seems to have little to no effect. Is there any way to ensure that we can receive a push token specifically to update the live activity after it starts? It seems to me that if a live activity can be started via push even when the app is fully terminated, and live activities are meant to reflect active information, then the mechanism to update it via a new token should also be able to work when the app is terminated. Both sequences are subscribed to within the AppDelegate upon initial app launch. This is what my code looks like at the moment: func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { Task { for await newToken in Activity<WidgetAttributes>.pushToStartTokenUpdates { let tokenString = newToken.map{ String(format: "%02x", $0) }.joined() // send to server } } Task { for await activity in Activity<WidgetAttributes>.activityUpdates { Task { for await token in activity.pushTokenUpdates { let tokenString = token.map { String(format: "%02x", $0) }.joined() // send to server } } } } } } Thanks in advance for any insights!
Replies
1
Boosts
0
Views
156
Activity
2w
LiveActivity via Push-To-Start and Update token questions.
We are implementing starting an activity via Push-To-Start. For the most part it works great, however we have run into a few edge cases. Currently, we send the "start activity" push notification and it creates the Activity as expected. If the app doesn't send an update token w/in a configured time, we assume the activity didn't start and try to start the activity again. Occasionally we get into a situation where there have been multiple activities started, but it should really only be one. Here is my theory: We store an auth token in the keychain for all REST endpoints if the phone has been restarted and not unlocked, the app doesn't have access to the auth token and fails to send the update token to our backend. Are there any best practices on how to manage PTS and UPDATE tokens? (updating these w/o authentication seems problematic)
Replies
1
Boosts
0
Views
291
Activity
1w
Do interactive LiveActivityIntent buttons keep the Lock Screen awake like Now Playing controls?
I am developing an iOS app using ActivityKit Live Activities with interactive buttons based on LiveActivityIntent. The implementation works correctly: LiveActivityIntent.perform() executes correctly. The Live Activity updates visually. MediaPlayer actions are triggered successfully. The app does not open when tapping the buttons. Repeated taps correctly update the Live Activity state. However, I observed a behavior difference on the Lock Screen: Now Playing controls keep the Lock Screen awake while interacting repeatedly. Apple Stopwatch/Timer controls also keep the Lock Screen awake while interacting. My app’s Live Activity fades to black after around 5–7 seconds even while the user continues tapping the Live Activity buttons. I also tested a third-party timer app with Live Activity buttons and observed the same fade-to-black behavior. I additionally tested: repeated Activity.update(...) calls after each tap; visual state updates after every interaction; multiple consecutive interaction updates. None of these prevented the Lock Screen from dimming/fading to black. So my question is: Is this expected behavior for third-party Live Activities using LiveActivityIntent? Or is there any recommended way to keep the Lock Screen interaction session active while the user is continuously interacting with Live Activity buttons? I am especially interested from an accessibility perspective, because short interaction windows can make repeated Lock Screen interactions more difficult for users with motor impairments or slower interaction patterns.
Replies
0
Boosts
0
Views
140
Activity
2w
Query regarding Live Activity push notification delivery and throttling behavior
We are using Live Activities in our iOS app to show real-time flight information on the Lock Screen and Dynamic Island. Our implementation currently works as follows: The Live Activity is created using the push-to-start token. After the Live Activity is started, our backend receives and uses the Live Activity update token to send updates to the Live Activity through APNs. The Live Activity content is updated through push notifications from our backend. These updates include flight status changes such as check-in status, boarding status, gate changes, delay updates, arrival status, and other journey-related states. We are observing an issue where some Live Activity state updates are not reflected on the device. From our backend logs, the APNs request is successfully sent, but in some cases the update does not appear to be received by the device, and the Live Activity remains in an older state. We understand from Apple documentation and platform behavior that Live Activity push updates may be subject to system-level throttling or delivery limitations. We would like to confirm the expected behavior and understand the recommended approach. Could you please help clarify the following? Are Live Activity update pushes subject to throttling by iOS/APNs even when the backend sends the update successfully? If APNs accepts the request successfully, is there still a possibility that the update may not be delivered to the device or may not update the Live Activity because of system-level throttling, device state, power conditions, network conditions, or Live Activity limits?
Replies
1
Boosts
0
Views
107
Activity
1w
Boarding pass Live Activity ignores localized destinationCityName — "Willkommen bei Munich" on de_DE device
Platform: iOS 26.5 · PassKit (semantic boarding pass) Summary When a .pkpass boarding pass uses the iOS 26 upgraded semantic format (preferredStyleSchemes: ["semanticBoardingPass", "boardingPass"]) for a real, scheduled flight that Apple's live flight data feed recognizes, the Wallet Live Activity (Lock Screen, Dynamic Island, and Wallet card "Welcome to …" copy) renders the destination city name in English, regardless of the value supplied in semantics.destinationCityName or the device's locale. On a German-locale iPhone, a flight arriving at MUC produces the grammatically broken string "Willkommen bei Munich" — German system-supplied prefix concatenated with the English city noun from Apple's flight data, instead of the expected "Willkommen in München". Steps to reproduce Build a .pkpass for any real, currently-scheduled flight whose destination city has a German-language variant (e.g. SK2657 CPH→MUC, 4Y1261 HER→MUC). Populate semantics with full iOS 26 fields including: "destinationAirportCode": "MUC", "destinationAirportName": "München", "destinationCityName": "München", "destinationLocationDescription": "Flughafen München Franz Josef Strauß" Install on an iPhone running iOS 26.1+ with Language: Deutsch, Region: Deutschland. Open the pass within Wallet's live-activity window. Expected: "Willkommen in München" Actual: "Willkommen bei Munich" What I believe is happening Apple's live flight data feed overrides the destinationCityName semantic tag with an English-only value sourced from the feed (presumably IATA / OAG). The iOS 26.1 liveDataConfiguration.excludedSemantics allow-list does not include destinationCityName or destinationAirportName, so there is currently no developer-side mechanism to either: submit a localized destination city, or opt out of the override while keeping live updates active. The PassKit destinationCityName schema is typed as a plain localizable string (single value), with no translations variant comparable to what some third-party pass APIs expose. The "localizable" annotation in the docs is misleading for this field, because pass.strings lookups are not applied to semantic values once the live flight feed supplies them. What I'd like to know Is this the intended behavior, or is destinationCityName missing from the documented excludedSemantics allow-list by omission rather than design? Is there a supported way for an airline (or a developer issuing passes on an airline's behalf) to ship localized destination city names that survive the live-data merge? If neither (1) nor (2): is there an intent to either localize Apple's flight-data city tokens by device locale, or expand excludedSemantics to cover destination/departure city + airport names in a future iOS 26.x release?
Replies
0
Boosts
0
Views
38
Activity
20h