We have implemented live activities with broadcast notification using channels. It has been working without a problem for the last 6-8 months. Now we want to upgrade it by starting the channel based live activity via push notification. Whenever I try locally with development channels there isnt any problem regarding to starting live activity.
When we go production on Testflight or App Store it doesn't work after first successful push even though user enters the app and send the new push to start token to our server and we are using the latest token we receive. We couldn't go further with debugging since it works perfectly fine the client when tried locally and we know we can send successful pushes as well since the metrics shows 12% success but we do not actually know what happened to remaining 88%. Every apns request return success with 200 and empty body. How can we further debug this issue. Or is this a common problem, if so, is there any possible solution to this.
As far as we see, token goes to our server so we have the latest token all the time and this whole logic doesn't work without deleting and reinstalling the app.
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
115 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hello everyone,
I am developing a Flutter iOS application that includes a Widget Extension + Live Activity (ActivityKit).
The project runs successfully on the iOS simulator when
launched directly from Xcode, but it cannot be signed properly via Flutter and I cannot upload the build to App Store Connect due to the following CodeSign error:
Command CodeSign failed with a nonzero exit code
Provisioning profile "…" doesn't include the entitlement:
com.apple.developer.activitykit.allow-third-party-activity
This error never goes away no matter what I try.
And the main problem is that my App ID does NOT show any ActivityKit or Live Activity capability in the Apple Developer portal → Identifiers → App ID.
So I cannot enable it manually.
However:
Xcode requires this entitlement
Flutter requires this entitlement
When I add the entitlement manually in the .entitlements file, Xcode says:
“This entitlement must be enabled in your Developer account. It cannot be added manually.”
So I am stuck in a loop where:
Apple Developer portal does not show ActivityKit capability
Xcode demands the ActivityKit entitlement
Signing fails
App Store upload fails
And Live Activity is a critical feature of my app
What I have already done
✔ “Automatically manage signing” is enabled
✔ Correct Team is selected for both Runner and the Widget Extension
✔ Bundle IDs are correct:
com.yksbuddy.app
com.yksbuddy.app.TimerWidgetExtension
✔ Deleted Derived Data completely
✔ Tried removing all ActivityKit-related entitlement keys manually
✔ Deleted Pods, reinstalled, rebuilt
✔ App Group settings match between Runner and Extension
✔ The same Live Activity code works perfectly in a clean Xcode-only project
✔ But fails only inside a Flutter project structure
✔ Xcode builds & runs on simulator, but App Store upload always fails due to missing entitlement
Core Problem:
In my Apple Developer “Identifiers → App ID” page, the Live Activity / ActivityKit capability does NOT appear at all, so I cannot enable:
Live Activities
ActivityKit
Third-party activity entitlement
Without being able to enable this capability, I cannot create a valid provisioning profile that includes:
com.apple.developer.activitykit.allow-third-party-activity
Flutter + Xcode insists this entitlement must exist, but Apple Developer portal does not give any option to enable it.
Topic:
Code Signing
SubTopic:
Certificates, Identifiers & Profiles
Tags:
WidgetKit
ActivityKit
Entitlements
When my app is in the background, I create a Live Activity through a push notification with token get from pushToStartTokenUpdates, and this process works fine. However, without opening the app, how can I retrieve the new push token for this Live Activity again and use it for subsequent updates to the Live Activity content?
Hello everyone,
I’m currently receiving feedback from clients in a production environment who are encountering a BadDeviceToken error with Live Activities, which is preventing their states from updating. However, for other clients, the token is working fine and everything functions as expected.
I’m collaborating with the back-end developers to gather more information about this issue, but the only log message we’re seeing is:
Failed to send a push, APNS reported an error: BadDeviceToken
I would greatly appreciate it if anyone could provide some insight or information on how to resolve this issue.
Good morning,
We are implementing Live Activities in a push-to-start flow. We wrap the listener for push to start tokens in a high priority task:
if ptsListenerTask == nil || ptsListenerTask?.isCancelled == true {
ptsListenerTask = Task(priority: .high) { [weak self] in
for await pushToken in Activity<LiveAuctionAttributes>.pushToStartTokenUpdates {
//Send token to back-end
}
}
I've tried a few variations of this and they work well on most devices. I have seen a couple of devices that refuse to issue a push to start token.
The user will have logging for the init flow and starting the PTS listener then the logs just go silent, nothing happens.
One thing that seemed to work was getting the user to start a Live Activity manually (from our debugging tool) then the PTS token gets issued.
This is not very reliable and working a mock live activity into the flow for obtaining a PTS token is a poor solution.
Is anyone else seeing this and is there a known issue with obtaining PTS tokens?
Thanks!
Brad
I’m manipulating some data inside a widget extension, and at the same time there is an active Live Activity (Dynamic Island / Lock Screen).
How can I update the Live Activity’s local notification when the data changes?
I tried accessing the current activity using Activity.activities, but it seems that this API is not accessible from inside the widget extension. What is the correct way to refresh or update the Live Activity in this case?
Hi everyone,
I am encountering an issue where my Live Activity (Dynamic Island) suddenly became invalid and failed to launch. It was working perfectly before, and I haven't modified any code since then.
My Environment:
Xcode: 26.1.1
Device iOS: 26.1
Testing: I also tested on iOS 18, but the Live Activity fails to start there as well.
Here is my code:
Live Activity Manager (Start/Update/End):
func startLiveActivity() {
// Initial static data
let attributes = SimpleIslandAttributes(name: "Test Order")
// Initial dynamic data
let initialContentState = SimpleIslandState(message: "Preparing...")
// Adapting for iOS 16.2+ new API (Content)
let activityContent = ActivityContent(state: initialContentState, staleDate: nil)
do {
let activity = try Activity.request(
attributes: attributes,
content: activityContent,
pushType: nil // Set to nil as remote push updates are not needed
)
print("Live Activity Started ID: \(activity.id)")
} catch {
print("Failed to start: \(error.localizedDescription)")
}
}
// 2. Update Live Activity
func updateLiveActivity() {
Task {
let updatedState = SimpleIslandState(message: "Delivering 🚀")
let updatedContent = ActivityContent(state: updatedState, staleDate: nil)
// Iterate through all active Activities and update them
for activity in Activity<SimpleIslandAttributes>.activities {
await activity.update(updatedContent)
print("Update")
}
}
}
// 3. End Live Activity
func endLiveActivity() {
Task {
let finalState = SimpleIslandState(message: "Delivered ✅")
let finalContent = ActivityContent(state: finalState, staleDate: nil)
for activity in Activity<SimpleIslandAttributes>.activities {
// dismissalPolicy: .default (immediate), .after(...) (delayed), .immediate (no animation)
await activity.end(finalContent, dismissalPolicy: .default)
print("End")
}
}
}
The Models (Shared between App and Widget Extension):
// 1. Define State (Dynamic data, changes over time, e.g., remaining delivery time)
public struct SimpleIslandState: Codable, Hashable {
var message: String
}
// 2. Define Attributes (Static data, constant after start, e.g., Order ID)
public struct SimpleIslandAttributes: ActivityAttributes {
public typealias ContentState = SimpleIslandState
var name: String // e.g., "My Order"
}
The Widget Code:
//
// SimpleIslandWidget.swift
// ReadyGo
//
// Created by Tang Yu on 2025/11/19.
//
import WidgetKit
import SwiftUI
import ActivityKit
struct SimpleIslandWidget: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(for: SimpleIslandAttributes.self) { context in
// UI shown on the Lock Screen
VStack {
Text("Lock Screen Notification: \(context.state.message)")
}
.activityBackgroundTint(Color.cyan)
.activitySystemActionForegroundColor(Color.black)
} dynamicIsland: { context in
// Inside Widget Extension
DynamicIsland {
// Expanded Region
DynamicIslandExpandedRegion(.center) {
Text("Test") // Pure text only
}
} compactLeading: {
Text("L") // Pure text only
} compactTrailing: {
Text("R") // Pure text only
} minimal: {
Text("M") // Pure text only
}
}
}
}
Additional Info:
This is the minimal code setup I created for testing, but even this basic version is failing.
I have set NSSupportsLiveActivities (Supports Live Activities) to YES (true) in the Info.plist for both the Main App and the Widget Extension.
Has anyone experienced this? Any help would be appreciated.
(I truly appreciate all the responses you all have written for me :bow: )
I was under the assumption that for Live Activity, in order for you to be able to update the Activity, you need an update token. And for the OS to issue you the update token, user must hit the "Allow" from the lock screen.
However based on these screenshots it seems that you don't need to hit "Allow" to be able to update the Live Activity.
Live Activity was updated — even without the user hitting "Allow"
So now I'm wondering if:
Is hitting Allow required for the update token to get issued? Or that assumption is incorrect? In our tests (when connected to Proxyman, the OS emits the update token after user hits "Allow" / "Always Allow")
If you don't hit allow, are there alternate ways to update the Live Activity without having the update token?
I'm guessing you could set a short stale time and then when the OS launches the app in the background you query the server and then update the Live Activity. Is that a worthy approach?
I also noticed that the "The Philly Inquirer" App has 'Background App Refresh" enabled, but this happened in 2 minutes. In our architecture assessments, after reviewing Apple's docs on 'Background Processing", we didn't think of it as a viable option, because it can't guarantee if the OS is given time in the next 2 minutes or 10 hours later when the phone is getting charged again.
Are any of these workarounds viable or are there alternate approaches?
Our requirement is:
be able to use Live Activity between 2-72hrs after app install. (I mention this because perhaps Apple may impost some restrictions for new installs)
be able to update an active Live Activity within 1-2 minutes after it has began.
Hi all, very new "developer" trying to build my own app. The app works, just trying to improve it.
I’m implementing a Live Activity in a widget extension (Swift/SwiftUI) for an app built with Flutter as the host app. ActivityKit is functioning correctly—activities start, update, and end normally, and the widget extension receives all state updates.
However, the Live Activity UI renders as a completely black capsule (both compact and expanded Dynamic Island, as well as the Lock Screen presentation). The system shows the Live Activity container, but none of the SwiftUI content displays.
Verified so far:
ActivityAttributes contains at least one stored property (previously empty).
ContentState fully Codable + Hashable.
All Dynamic Island regions return visible test UI (Text/Image).
No .containerBackground() usage.
Added explicit .activityBackgroundTint() + system foreground colors.
All Swift files included in widget extension target.
No runtime errors, no decode failures, no SwiftUI logs.
Widget previews work.
Clean build, app reinstall, device reboot.
Entitlements and Info.plist appear valid.
Problem:
The widget extension returns a completely black UI on-device, despite valid SwiftUI content in ActivityConfiguration. The Live Activity “shell” renders, so the activity is recognized, but the widget’s view hierarchy is visually empty.
Question:
Under what conditions would a widget extension produce a black, empty UI for a Live Activity even when ActivityKit, previews, and the SwiftUI layout are correct?
Are there known cases where:
Widget extension Info.plist misconfiguration,
Incorrect background/tint handling,
Rendering issues in Dynamic Island,
Host app integrations (Flutter),
Or extension isolation issues
cause valid SwiftUI to fail to render in a Live Activity?
Any guidance on deeper debugging steps or known system pitfalls would be appreciated.
I'm specifically focused on Live Activity, but I think this is somewhat a general question. The app could get a few callbacks when:
There's a new payload (start, update, end)
There's a new token (start, update)
There's some other lifecycle event (stale, dismissed)
Assuming that the user didn't force kill the app, would the app get launched in all these scenarios?
When OS launches the app for a reason, should we wrap our tasks with beginBackgroundTask or that's unnecessary if we're expecting our tasks to finish within 30 seconds? Or the OS may sometimes be under stress and give you far less time (example 3 seconds) and if you're in slow internet, then adding beginBackgroundTask may actually come in handy?
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
APNS
Background Tasks
ActivityKit
Having some discussion about when we should clear out a token from our servers.
Docs say:
Don’t retry notification responses with the error code BadDeviceToken, DeviceTokenNotForTopic, Forbidden, ExpiredToken, Unregistered, or PayloadTooLarge. You can retry with a delay, if you get the error code TooManyRequests.
The way I see it is that with the exception of PayloadTooLarge, all other errors means you should remove the token from your server. Either because:
The token is no longer good
The token is good, but this is just not the right:
environment (sandbox vs production)
topic (the token is from a different bundle id or developer team)
target (app vs live activity appex)
Do I have it right?
Extra context: when using the "JSON Web Token Validator" tool, a colleague reported that a 410 -Expired token (from couple days back) was still valid today. This raises questions about when tokens should actually be deleted and how these error codes should be interpreted.
Also is it possible for the docs to get updated for us to explicitly know if a token should get removed and not leave it for interpretation?
Hey!
I'm working on enabling remotely started live activities. I'm running into 2 crashes:
Upon initializing ActivityAuthorizationInfo
Upon calling Activity<...>.activities array
Both stack traces look like this:
0 libsystem_kernel.dylib +0xce0 _mach_msg2_trap
1 libsystem_kernel.dylib +0x4398 _mach_msg2_internal
2 libsystem_kernel.dylib +0x42b4 _mach_msg_overwrite
3 libsystem_kernel.dylib +0x40fc _mach_msg
4 libdispatch.dylib +0x1cc04 __dispatch_mach_send_and_wait_for_reply
5 libdispatch.dylib +0x1cfa4 _dispatch_mach_send_with_result_and_wait_for_reply
6 libxpc.dylib +0x107ec _xpc_connection_send_message_with_reply_sync
7 BoardServices +0xaea8 -[BSXPCServiceConnectionMessage _sendWithMode:]
8 BoardServices +0x17938 -[BSXPCServiceConnectionMessage sendSynchronouslyWithError:]
9 BoardServices +0xeef0 ___71+[BSXPCServiceConnectionProxy createImplementationOfProtocol:forClass:]_block_invoke
They happen to a limited number of users, but not insignificant. Most are on iOS 18.6.2 and iOS 26.1, but there are others in the mix. I don't have a repro myself. It looks like the main thread gets blocked after we receive no response from these ActivityKit APIs. Both of these are called inside application:didFinishLaunchingWithOptions:.
For ActivityAuthorizationInfo, we need the app to communicate with the server whether the user has live activities enabled; hence, calling this object's init as early as possible in the app.
For activities array, I'd like to do some logging whenever the live activity is started or ended (for example, if activities array no longer contains any activities, we can log the activity as dismissed). For this logging to happen, as far as I understand, it has to happen inside didFinishLaunchingWithOptions since this is the only method being called upon the terminated app receiving background runtime when the live activity starts/ends remotely.
After some research, one potential reason is ActivityKit APIs are just not ready to return values via xpc connection at app startup, so moving these methods to applicationDidBecomeActive could resolve the problem. That's fine for ActivityAuthorizationInfo init, but for accessing activities, there is no other place in the lifecycle to see if an activity has been dismissed (especially in the scenario where app is terminated, so we get only 30 seconds ish of background runtime).
Curious if anyone has run into this or has any insights into ActivityKit API behavior.
For our Live Activity Tokens, when we fire a payload, often apns is returning a response of 410 unregistered.
Docs are saying:
The device token is inactive for the specified topic. There is no need to send further pushes to the same device token, unless your application retrieves the same device token, refer to Registering your app with APNs
Questions:
Why does this happen? Does it only happen because the user changed their permission? Or there are other reasons?
And when it does happen, what should we do about it?
A. Should we keep the token on the server? Because perhaps the user will change their permission and the token becomes valid? That could leave us with lots of invalid tokens and us firing at them unnecessarily.
Docs do say:
Don’t retry notification responses with the error code BadDeviceToken, DeviceTokenNotForTopic, Forbidden, ExpiredToken, Unregistered, or PayloadTooLarge.
B. Or should we remove the token from the server? That then requires app to re-register the token. But the problem with that is:
When I went into App's settings from OS settings and toggled push notifications to on, the app was not launched into the background nor killed i.e. it requires explicit app launch by the user to re-register itself which isn't ideal...
It means a user may turn on notifications from the OS settings and then assume that their push notifications should be back in business, but that won't happen if you toggle things from OS settings.
I am developing a live activity for my app and am running into issues on devices with dynamic islands. The live activity will randomly get in a state where it displays a spinner and does not update. For devices without dynamic islands, the activity works perfectly fine.
I have tried breaking down the views to determine the root cause, but at times it seems very random. These are all TestFlight builds as we are currently developing the feature.
I have tried using the console app and looking at the various processes that have been called out in other threads and cannot see any actual errors being logged.
Looking for any pointers on how to pinpoint the root cause of this issue.
I have developed a LiveActivity on my product that supports DynamicIsland. Recently, two users encountered this situation while updating the app:
LiveActivity was created with a status of. active, but after 100ms, it immediately started displaying as. dimiss. This process was repeated many times until the user restarted their iPhone and the display became normal
A user's LiveActivity was successfully created with a status of. active, and the data was updated using the. update method normally; But this user's interface keeps showing a gray component empty state
I am unable to obtain useful information regarding the bug encountered in processing. I would like to know how to obtain the reason why the user's LiveActivity has been modified to. dimiss by the iOS system in the face of these situations; How can I obtain useful information to determine the cause of the error when the user interface cannot display data without debugging.
Thank you~
I'm struggling to understand what the impact of this flag is.
Docs only say:
For devices running iOS 18 and iPadOS 18 or later, you can add input-push-token: 1 to your payload to start a Live Activity and receive a new push token. After you receive a new push token, you can use it to send updates to a Live Activity.
But things were working fine for iOS 17. Right?
Does it somehow make the OS emit update tokens faster/more successfully?
Should I include in all start, update, end events?
Hello,
I would like to inquire about a specific behavior I've observed with Live Activities to determine if it is a bug.
When our application is closed but the device is in use, an alarm triggers a Live Activity to appear at the top of the screen. However, it seems that tapping the background area of this Live Activity does not trigger the .widgetURL and .onOpenURL
Could you please confirm if this is the intended behavior? or should I config another setting for desired action like trigger .onOpenURL?
Thank you for your time and assistance.
Best regards,
Hello,
I have a question regarding the control over the Dynamic Island UI when my app is in the foreground.
Scenario:
A user is playing a song on Apple Music, so its Live Activity is active and visible in the Dynamic Island.
Then, the user opens my app.
Desired Behavior:
While my app is in the foreground, I would like to temporarily hide or dismiss the dynamic island from Apple Music to provide a more immersive experience. When the user navigates away from my app, it's perfectly fine for the Dynamic Island to show dynamic island again.
Is there an API that allows an app to temporarily suppress a Live Activity that was initiated by another application?
My understanding of the iOS sandbox model suggests this might not be possible for security and privacy reasons, but I wanted to confirm if there's an intended way to handle this, especially for full-screen apps like games or video players.
Thank you!
The APP was not awakened by system after start a liveactivity and the liveactivity has showed on lock screen.so the updatetoken wont send to our inner server and the liveactivity can not update,often like this,but sometimes it can work.
it makes me confuse,and i don't know how should i can do,because the liveactivity like a black box,i can not analyse the data link.for example ,inner server send a start liveactivity,but it can not accept a updatetoken unless the user lanuch APP.
i hope the liveactivity can start and update on background. And i have developed it as described in the document.
Hope to get your help,thank you very much.
Just wanted to clarify some expected behaviors here. It seems that there are two distinct behaviors for Live Activity flows for freshly installed apps.
When you start a Live Activity for the first time and the user hasn't yet clicked on Allow/Don't Allow in the activity interface, there are two different sequences:
Starting a Live Activity locally
Request a Live Activity locally via Swift
Live Activity starts
.pushTokenUpdates is immediately triggered, even if the Allow/Don't Allow buttons appear under the Activity UI
Starting a Live Activity via push-to-start
Send a push-to-start notification to launch a Live Activity
Live Activity starts
.pushTokenUpdates is not triggered, and .pushToken returns nil.
If a user clicks on Allow in the Activity UI, only then is .pushTokenUpdates triggered.