I'm seeing a Live Activity that's ended almost immediately after I'm creating it. I'm not ending the activity in my code, so something is happening at the system level. iOS version is 18.3.1.
Looking at the logs for liveactivitiesd, I see that it was successfully created:
default 12:57:34.837266-0800 liveactivitiesd Created activity: 22713DF6-E853-4B34-85FA-CD08D8FCA91B
default 12:57:34.837639-0800 liveactivitiesd Starting activity: identifier: 22713DF6-E853-4B34-85FA-CD08D8FCA91B; createdDate: 2025-02-17 20:57:34 +0000; state: active; deviceIdentifier: local; resolvedContentSources: [ActivityKit.ActivityContentSource.process(target: <snip>), ActivityKit.ActivityContentSource.sync]; lastUpdateDate: 2025-02-17 20:57:34 +0000; endingOptions: nil
default 12:57:34.858701-0800 liveactivitiesd Activity did start 22713DF6-E853-4B34-85FA-CD08D8FCA91B
But then moments later, it's immediately ended:
default 12:57:34.933963-0800 liveactivitiesd Ending activity 22713DF6-E853-4B34-85FA-CD08D8FCA91B for XPC participant content source <private>
default 12:57:34.933983-0800 liveactivitiesd Stopping activity: 22713DF6-E853-4B34-85FA-CD08D8FCA91B
default 12:57:34.934019-0800 liveactivitiesd Activity: identifier: 22713DF6-E853-4B34-85FA-CD08D8FCA91B; createdDate: 2025-02-17 20:57:34 +0000; state: active; deviceIdentifier: local; resolvedContentSources: [ActivityKit.ActivityContentSource.process(target: <snip>), ActivityKit.ActivityContentSource.sync]; lastUpdateDate: 2025-02-17 20:57:34 +0000; endingOptions: nil should be discarded now
default 12:57:34.934442-0800 liveactivitiesd Activity discarded: 22713DF6-E853-4B34-85FA-CD08D8FCA91B
Again, I'm not ending this activity in my code. I'll occasionally see this happen in my app, and the only solution I've found is to restart my device. Afterwards, everything seems fine.
Is this a bug?
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
122 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Hello,
I'm trying to display some Duration in a live activity using a custom format, with the goal of displaying a match time (only minutes) as, e.g. 33', 45' (+2), etc.
For that purpose, I'm using a TimeDataSource<Duration>, so that it also updates automatically given a starting point.
I've implemented my custom FormatStyle, trying to somehow mimic the existing UnitsFormatStyle (which perfectly works with live activities) but just changing the format.
I've added conformance to DiscreteFormatStyle, and code-wise everything seems to be ok (if I've understood things correctly). It compiles and it even works as expected in a playground.
However, when trying to use it within the live activity, I'm getting these cryptic errors in the Console.app, and the live activity just turns into a view with placeholders
Failed to fetch view from archive at index 12: SwiftUI.AnyCodable<SwiftUI.(unknown context at $1d47f6af0).SafelyCodableRequirement>.(unknown context at $1d47fe410).Errors.noType(mangledName: "7SwiftUI18TimeDataFormattingO10ResolvableVy_AA0cD6SourceVAAE15DurationStorageOys0H0V_GAK28BlickLiveActivitiesExtensionE16MatchFormatStyleVG")
[624AEC37-13D9-4927-9F41-C3092B61E214] Failed to return view entry from archive for view model with tag listItem with error: SwiftUI.AnyCodable<SwiftUI.(unknown context at $1d47f6af0).SafelyCodableRequirement>.(unknown context at $1d47fe410).Errors.noType(mangledName: "7SwiftUI18TimeDataFormattingO10ResolvableVy_AA0cD6SourceVAAE15DurationStorageOys0H0V_GAK28BlickLiveActivitiesExtensionE16MatchFormatStyleVG")
Are there any limitations when it comes to live activities and these custom formatters? This whole error doesn't make sense, since I'm only aiming to update every minute, which should just be fine, the same thing I get with the UnitsFormatStyle.
For reference, this is my playground, which just works as expected:
import Foundation
import SwiftUI
import PlaygroundSupport
extension Duration {
struct MatchFormatStyle: DiscreteFormatStyle, Sendable {
let periodLength: Int
let overtime: Int
func format(_ value: Duration) -> String {
let (seconds, _): (Int64, Int64) = value.components
let minutes: Int = Int(seconds) / 60
let current: Int = periodLength + minutes + overtime
if current > periodLength {
return "\(periodLength)' (+\(current - periodLength))"
} else {
return "\(current)'"
}
}
func discreteInput(before input: Duration) -> Duration? {
let (seconds, _): (Int64, Int64) = input.components
let minutes: Int64 = seconds / 60 - 1
return Duration(secondsComponent: minutes * 60, attosecondsComponent: .zero)
}
func discreteInput(after input: Duration) -> Duration? {
let (seconds, _): (Int64, Int64) = input.components
let minutes: Int64 = seconds / 60 + 1
return Duration(secondsComponent: minutes * 60, attosecondsComponent: .zero)
}
}
}
extension FormatStyle where Self == Duration.MatchFormatStyle {
static func matchTime(currentTime: Int, periodLength: Int) -> Duration.MatchFormatStyle {
return Duration.MatchFormatStyle(periodLength: periodLength, overtime: max(currentTime - periodLength, .zero))
}
}
extension TimeDataSource<Date> {
static func matchDuration(for currentTime: Int, periodLength: Int) -> TimeDataSource<Duration> {
let minutesAhead: Double = Double(max(periodLength - currentTime + 1, .zero))
return TimeDataSource<Date>.durationOffset(to: Date.now.addingTimeInterval(minutesAhead * 60))
}
}
struct FooView: View {
let currentTime: Int = 36
let periodLength: Int = 45
var body: some View {
Text(
TimeDataSource<Date>.matchDuration(for: currentTime, periodLength: periodLength),
format: .matchTime(currentTime: currentTime, periodLength: periodLength)
)
.frame(width: 400, height: 200)
.font(.system(size: 50))
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.setLiveView(FooView())
Any hints or suggestions are welcome, many thanks in advance.
we have three problem when using the push notification on Live Activity.
1. What is the specific callback strategy for the activityUpdates property in ActivityKit?
We found that in actual user scenarios, there is a probability that we may not receive callbacks. From the community experience, there are some resource optimization strategies that do not perform callbacks. From this perspective, the explanation is kind of vague. Is there any clear feedback to understand why callbacks are performed/not performed?
2.what is the specific description of the wake-up strategy, when background app receive Live Activity offline start Push?
From community experience, we can see that the system may wake up for a duration of 0-30s due to resource optimization strategies, or not wake up/not deal with it. Is there an official description of the wake-up strategy? or we also have to follow this description:
Wake up of apps using content-available pushes are heavily throttled. You can expect 1-2 wakeup per hour as a best case scenario in the hands of your users. so this cannot be assumed to be a reliable wake-up on demand mechanism for an app.
3 How can we determine user have selected (allow or always allow) of the Live Activity permission?
When we use real-time activity offline push, there are two system prompts in iOS:
the first prompt : allow and disallow real-time activity
the second prompt : always allow and disallow
Is there an interface that can directly determine which permission the user has chosen (allow/always allow)? (By the way, we can get disallow status).
At present, we haven't seen any interface in the official documentation/interface that can determine (allow/always allow). The difference here will affect the generation of Update Token. Without Update Token, we can not update our activity instance.
Is it possible to display a live activity on the lock-screen without a dynamic island? Or at least without expanding the dynamic island more than just for a small icon?
struct SomeWidgetLiveActivity: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(for: SomeAttributes.self) { context in
} dynamicIsland: { context in
DynamicIsland {
DynamicIslandExpandedRegion(.leading) {
// Seems to be mandatory, any way around it?
}
} compactLeading: {
} compactTrailing: {
} minimal: {
}
}
I couldn't quite find a way.
Thank you
not sure where to post this hence adding here.
how to run in this full screen mode even when the screen is locked. As far as I looked, it’s only live activities that the developers are made available with. Is there a way to create our own UI on lockscreen, given a similar usecase exists?
How to execute code on main app when interacted with a live activity, given that they are already interactable.
is there a way without opening the app?
what are the best ways?
i got some problem for the LiveAcitvity when i start it with notification.
The LiveActivity can not show,but it can work when i update or end a LiveActitvity;
And so,i think my configeration is right like the code;
thanks in advance
Live activity does not update its content's text color when the iPhone goes to sleep mode. Only the background color of live activity changes to dark mode but all the contents stay in light mode.
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.
Hello everyone,
I have an app leveraging SwiftData, App Intents, Interactive Widgets, and a Control Center Widget. I recently added Live Activity support, and I’m using an App Intent to trigger the activity whenever the model changes.
When the App Intent is called from within the app, the Live Activity is created successfully and appears on both the Lock Screen and in the Dynamic Island. However, if the same App Intent is invoked from a widget, the model is updated as expected, but no Live Activity is started.
Here’s the relevant code snippet where I call the Live Activity:
`
await LiveActivityManager.shared.newSessionActivity(session: session)
And here’s how my attribute is defined:
struct ContentState: Codable, Hashable {
var session: Session
}
}
Is there any known limitation or workaround for triggering a Live Activity when the App Intent is initiated from a widget? Any guidance or best practices would be greatly appreciated.
Thank you!
David
I've built an app that supports live activities, but when trying to build and deploy I'm getting the error:
Provisioning profile "iOS Team Provisioning Profile doesn't include the com.apple.developer.live-activity entitlement."
Looking in Xcode - under signing and provisions, there is no "Live Activity" option to select.
Looking in the developer portal, similarly under Certificates, Identifiers & Profiles, there is no "Live Activity" option.
I've added com.apple.developer.live-activity to my entitlements file for both my widget and my main app target, and added NSSupportsLiveActivities to my info.plist files.
I'm building on Xcode Version 16.0
Any ideas on how to fix this? Super confused!
Thanks in advance!
My app will be woken when Activity.pushToStartTokenUpdates delivered the new token.
But I want to know how can I get the activity.pushTokenUpdates when my server start an live activity via push notification, because without the activity.pushTokenUpdates, my server can't deliver update information after start the live activity.
For now, I check the activities when my app switch foreground/background. But how can I be notified when my app is in foreground and server start an live activity by push notification.
I've tried "content-available": 1 in LA's payload aps, but I also can't be notified in the didReceiveRemoteNotification in appDelegate.
I have a UIApplicationDelegate, where I want to terminate a live activity (in dynamic island) in applicationWillTerminate. However, ending an activity is asynchronous. When I end it within a Task, it's never called.
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?
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.
I read from https://developer.apple.com/documentation/ActivityKit/starting-and-updating-live-activities-with-activitykit-push-notifications#Start-new-Live-Activities-with-ActivityKit-push-notifications
that I can start a live activity from CUSTOM SERVER by the start token I get from MyApp.Does that paragraph means my CUSTOM SERVER can receive a new token from aps?
If not, how can update the live activity started by Push-Notification when MyApp doesn't alive?
And what "input-push-token: 1 " can do, when I put it in the payloads?
Our app occasionally crashes when creating a Live Activity using ActivityKit.
Crash log analysis indicates a wild pointer issue originating within ActivityKit.
The crash appears to be linked to the coexistence of multiple Live Activities.
Could this be a compatibility issue with ActivityKit?
We would appreciate any guidance or potential workarounds to resolve this issue.
Looking forward to your response.
Thread 0 Crashed:
0 ActivityKit 0x000000023023d034 0x230235000 + 32820 ( + 13792)
1 ActivityKit 0x000000023023d014 0x230235000 + 32788 ( + 13760)
2 Combine 0x00000001ac5bd168 0x1ac5b5000 + 33128 ( + 292)
3 Combine 0x00000001ac5c0658 0x1ac5b5000 + 46680 ( + 24)
4 Combine 0x00000001ac5d1714 0x1ac5b5000 + 116500 ( + 204)
5 Combine 0x00000001ac5c8da0 0x1ac5b5000 + 81312 ( + 24)
6 Combine 0x00000001ac5e8e98 0x1ac5b5000 + 212632 ( + 2520)
7 Combine 0x00000001ac5d1a4c 0x1ac5b5000 + 117324 ( + 24)
8 Combine 0x00000001ac68316c 0x1ac5b5000 + 844140 ( + 56)
9 Combine 0x00000001ac5d4a4c 0x1ac5b5000 + 129612 ( + 176)
10 Combine 0x00000001ac5bd43c 0x1ac5b5000 + 33852 ( + 392)
11 Combine 0x00000001ac5b7198 0x1ac5b5000 + 8600 ( + 24)
12 Combine 0x00000001ac5ead74 0x1ac5b5000 + 220532 ( + 712)
13 Combine 0x00000001ac5e2320 0x1ac5b5000 + 185120 ( + 24)
14 Combine 0x00000001ac5bfe74 0x1ac5b5000 + 44660 ( + 488)
15 Combine 0x00000001ac5b81b8 0x1ac5b5000 + 12728 ( + 24)
16 Combine 0x00000001ac5b8804 0x1ac5b5000 + 14340 (Just.receive(subscriber:) + 424)
17 Combine 0x00000001ac5f7a7c 0x1ac5b5000 + 273020 (Publishers.Merge.receive(subscriber:) + 820)
18 Combine 0x00000001ac5d9850 0x1ac5b5000 + 149584 (PublisherBox.receive(subscriber:) + 108)
19 Combine 0x00000001ac5b8154 0x1ac5b5000 + 12628 (AnyPublisher.receive(subscriber:) + 64)
20 Combine 0x00000001ac5dc9cc 0x1ac5b5000 + 162252 ( + 548)
21 Combine 0x00000001ac5dc764 0x1ac5b5000 + 161636 (Publishers.HandleEvents.receive(subscriber:) + 620)
22 Combine 0x00000001ac5d9850 0x1ac5b5000 + 149584 (PublisherBox.receive(subscriber:) + 108)
23 Combine 0x00000001ac5b8154 0x1ac5b5000 + 12628 (AnyPublisher.receive(subscriber:) + 64)
24 Combine 0x00000001ac5d92e8 0x1ac5b5000 + 148200 (Publishers.FlatMap.receive(subscriber:) + 416)
25 Combine 0x00000001ac5dc9cc 0x1ac5b5000 + 162252 ( + 548)
26 Combine 0x00000001ac5d9850 0x1ac5b5000 + 149584 (PublisherBox.receive(subscriber:) + 108)
27 Combine 0x00000001ac5b8154 0x1ac5b5000 + 12628 (AnyPublisher.receive(subscriber:) + 64)
28 Combine 0x00000001ac5f062c 0x1ac5b5000 + 243244 (Publishers.CompactMap.receive(subscriber:) + 572)
29 Combine 0x00000001ac5d9850 0x1ac5b5000 + 149584 (PublisherBox.receive(subscriber:) + 108)
30 Combine 0x00000001ac5b8154 0x1ac5b5000 + 12628 (AnyPublisher.receive(subscriber:) + 64)
31 Combine 0x00000001ac5e64e4 0x1ac5b5000 + 201956 (Publishers.SetFailureType.receive(subscriber:) + 552)
32 Combine 0x00000001ac5d92e8 0x1ac5b5000 + 148200 (Publishers.FlatMap.receive(subscriber:) + 416)
33 Combine 0x00000001ac5dc9cc 0x1ac5b5000 + 162252 ( + 548)
34 Combine 0x00000001ac5d9850 0x1ac5b5000 + 149584 (PublisherBox.receive(subscriber:) + 108)
35 Combine 0x00000001ac5b8154 0x1ac5b5000 + 12628 (AnyPublisher.receive(subscriber:) + 64)
36 Combine 0x00000001ac5f062c 0x1ac5b5000 + 243244 (Publishers.CompactMap.receive(subscriber:) + 572)
37 Combine 0x00000001ac5d9850 0x1ac5b5000 + 149584 (PublisherBox.receive(subscriber:) + 108)
38 Combine 0x00000001ac5b8154 0x1ac5b5000 + 12628 (AnyPublisher.receive(subscriber:) + 64)
39 Combine 0x00000001ac5bdd68 0x1ac5b5000 + 36200 (Publishers.ReceiveOn.receive(subscriber:) + 812)
40 Combine 0x00000001ac5f1e10 0x1ac5b5000 + 249360 (Publisher.sink(receiveCompletion:receiveValue:) + 304)
41 ActivityKit 0x00000002302594a0 0x230235000 + 148640 ( + 6064)
42 ActivityKit 0x0000000230258c18 0x230235000 + 146456 ( + 3880)
43 ActivityKit 0x0000000230258410 0x230235000 + 144400 ( + 1824)
44 ActivityKit 0x0000000230258124 0x230235000 + 143652 ( + 1076)
45 ActivityKit 0x0000000230258080 0x230235000 + 143488 ( + 912)
46 ActivityKit 0x000000023026d280 0x230235000 + 230016 ( + 4228)
47 ActivityKit 0x000000023026d39c 0x230235000 + 230300 ( + 4512)
48 libswiftDispatch.dylib 0x00000001ac59e7f4 0x1ac59d000 + 6132 ( + 28)
49 libswiftDispatch.dylib 0x00000001ac5a5a90 0x1ac59d000 + 35472 ( + 16)
50 libswiftDispatch.dylib 0x00000001ac59f97c 0x1ac59d000 + 10620 ( + 188)
51 libswiftDispatch.dylib 0x00000001ac59fa90 0x1ac59d000 + 10896 ( + 28)
52 libswiftDispatch.dylib 0x00000001ac59f5ec 0x1ac59d000 + 9708 ( + 28)
53 libdispatch.dylib 0x00000001ab37feac 0x1ab37c000 + 16044 ( + 20)
54 libdispatch.dylib 0x00000001ab38f428 0x1ab37c000 + 78888 ( + 56)
55 libswiftDispatch.dylib 0x00000001ac59ef38 0x1ac59d000 + 7992 ( + 180)
56 libswiftDispatch.dylib 0x00000001ac59e0dc 0x1ac59d000 + 4316 ( + 56)
57 libswiftDispatch.dylib 0x00000001ac59ec48 0x1ac59d000 + 7240 ( + 396)
58 libswiftDispatch.dylib 0x00000001ac59e188 0x1ac59d000 + 4488 (OS_dispatch_queue.sync(execute:) + 164)
59 ActivityKit 0x000000023026be70 0x230235000 + 224880 ( + 3228)
60 ActivityKit 0x000000023026b400 0x230235000 + 222208 ( + 556)
61 ActivityKit 0x00000002302d10b4 0x230235000 + 639156 ( + 25780)
62 ActivityKit 0x00000002302d0cd0 0x230235000 + 638160 ( + 24784)
63 ActivityKit 0x00000002302d0b94 0x230235000 + 637844 ( + 24468)
64 xxxx 0x0000000100919638 specialized static LiveActivityManager.startActivity(title:) + 169528 (LiveActivityManager.swift:96)
I'm implementing iOS Live Activities in my Flutter app using the live_activities package. While the activity seems to be created (I can get the activity token, and clicking the Dynamic Island opens the app), the LiveActivity UI does not show up as expected.
Logs: The following errors/warnings appear in the logs:
Not updating lastKnownShmemState in CFPrefsPlistSource<0x6000006bc7e0> (Domain: group.powerdock.sessionactivity, User: kCFPreferencesCurrentUser, ByHost: No, Container: (null), Contents Need Refresh: No): 34 -> 33
What Works: The activity token is created successfully. Clicking the Dynamic Island opens my app.
What Does Not Work: The LiveActivity UI does not display on the lock screen or elsewhere.
Hello,
I am experiencing an issue with the Live Activity feature in my application. Despite extensive debugging efforts, the problem persists, and I would greatly appreciate your assistance.
Here are the key details of the issue:
We are not using APNS; everything related to Live Activities is handled locally within the app.
The Live Activity displays task details, including: Task title, icon and A label functioning as a timer that shows the remaining time in seconds for the task.
The Live Activity appears as expected when the app is opened. However, when the app is sent to the background, the Live Activity does not appear consistently. It disappears unexpectedly in some random instances.
I have tried various debugging methods, including:
Ensuring the activity is correctly created and updated as per the Apple Documentation.
Verifying the ActivityAttributes and ActivityContentState configurations.
Testing with different app lifecycle events to determine when the issue occurs.
Despite these efforts, the issue remains unresolved, and the cause is unclear. The app behavior seems inconsistent, as the Live Activity sometimes remains visible and at other times disappears when the app is backgrounded.
I would greatly appreciate your help in understanding and addressing this issue. Specifically:
Are there any system-level constraints or conditions that could cause a Live Activity to terminate when the app is backgrounded?
Are there best practices or configurations to ensure the persistence of locally managed Live Activities?
Can you suggest additional debugging techniques or tools that could help identify the root cause?
Thank you for your time and support. Please let me know if further information or logs are needed to assist in troubleshooting
Hello,
I am experiencing an issue with the Live Activity feature in my application. Despite extensive debugging efforts, the problem persists, and I would greatly appreciate your assistance.
Here are the key details of the issue:
We are not using APNS; everything related to Live Activities is handled locally within the app.
The Live Activity displays task details, including: Task title, icon and A label functioning as a timer that shows the remaining time in seconds for the task.
The Live Activity appears as expected when the app is opened. However, when the app is sent to the background, the Live Activity does not appear consistently. It disappears unexpectedly in some random instances.
I have tried various debugging methods, including:
Ensuring the activity is correctly created and updated as per the Apple Documentation.
Verifying the ActivityAttributes and ActivityContentState configurations.
Testing with different app lifecycle events to determine when the issue occurs.
Despite these efforts, the issue remains unresolved, and the cause is unclear. The app behavior seems inconsistent, as the Live Activity sometimes remains visible and at other times disappears when the app is backgrounded.
I would greatly appreciate your help in understanding and addressing this issue. Specifically:
Are there any system-level constraints or conditions that could cause a Live Activity to terminate when the app is backgrounded?
Are there best practices or configurations to ensure the persistence of locally managed Live Activities?
Can you suggest additional debugging techniques or tools that could help identify the root cause?
Thank you for your time and support. Please let me know if further information or logs are needed to assist in troubleshooting
STEPS TO REPRODUCE
Download and Install the Owaves App from the App Store.
Create a Live Activity:
Open the app and create an activity for the current time on Today.
Example: If the current time is 9:30 AM, create an activity with a time range such as 9:00 AM - 10:00 AM to ensure it is live.
Enable Live Activity:
Tap on the newly created activity to open the Event Details page.
Scroll to the bottom of the page and locate the toggle switch labeled "Live Activity".
Switch the toggle to the ON position to enable the Live Activity.
Background the App:
Send the app to the background.
Check the Lock Screen:
Swipe down to enable iOS' Lock Screen and check for the Live Activity from the Owaves app.
Repeat the Steps:
If the Live Activity appears on the Lock Screen initially, repeat steps 3-5 multiple times.
Eventually, you will encounter instances where the Live Activity does not appear on the Lock Screen, despite following the same process
I'm implementing a timer feature and facing the issue that the live activity I'm starting just continues showing after the timer is complete.
The body of the live activity widget is more or less:
ActivityConfiguration(for: WhendyWidgetAttributes.self) { context in
VStack {
Text(
context.state.timerEndDate,
style: .timer
)
// if Date.now < timerEndTime { Text("Done") }
self.expandedView(state: context.state)
}
} …
Ideally I could get the activity to show something else when it is done but I don't know how to get it to re-evaluate it's body once the end time is reached.
I create the activity with
let activity = try ActivityKit.Activity.request(
attributes: attributes,
content: .init(
state: .init(timerEndDate: timerEndDate),
staleDate: timerEndDate
),
pushType: nil
)
Can I schedule the activity to do a refresh it's body (and reevaluating Date.now) once the timerEndDate is reached?
Considered Approaches
trying staleDate
However, the activity never shows that it has become stale. Would it be expected that it shows the stale-ness?
scheduling dismissal
I also thought about starting and immediately stopping the activity with a delayed dismissal, but unfortunately it seems this is limited to a 4 hour window, and I'd like longer timers too.
remote updates
I understand I could use remote notifications to update the live activity, but I'd really like to keep things local as all the functionality is locally plannable.
Background Tasks
I understand these don't run reliably or at a predictable time.
A Timer in the app that updates the content
I think this would only update the activity while the app is in foreground.