Widgets & Live Activities

RSS for tag

Discuss how to manage and implement Widgets & Live Activities.

WidgetKit Documentation

Posts under Widgets & Live Activities subtopic

Post

Replies

Boosts

Views

Activity

Unable perform AppIntent in interactive Widget
I am currently developing an interactive widget, but an AppIntent issue blocked me for 2 days. I have an AppIntent named TimerActionIntent, which has two parameters: TimerType and TimerAction. Here is the code: import AppIntents enum TimerType: Int, CaseIterable, AppEnum, AppEntity { case sleep case feeding static let typeDisplayRepresentation: TypeDisplayRepresentation = "Timer Type" static let caseDisplayRepresentations: [TimerType : DisplayRepresentation] = [ .sleep: "Sleep", .feeding: "Feeding" ] } enum TimerAction: Int, CaseIterable, AppEnum, AppEntity { case start case pause case stop static let typeDisplayRepresentation: TypeDisplayRepresentation = "Timer Action" static let caseDisplayRepresentations: [TimerAction : DisplayRepresentation] = [ .start: "Start", .pause: "Pause", .stop: "Stop" ] } struct TimerActionIntent: AppIntent { static let title: LocalizedStringResource = "Operate a Log Timer" @Parameter(title: "Timer", default: .sleep) var timerType: TimerType @Parameter(title: "Action", default: .start) var action: TimerAction static var isDiscoverable: Bool = false static var openAppWhenRun: Bool = false init() {} init(timerType: TimerType, action: TimerAction) { self.timerType = timerType self.action = action } func perform() async throws -> some IntentResult { // perform the action Self.openAppWhenRun = state == .stopped } return .result() } } I can't execute the AppIntent if using the following code: Button(intent: TimerActionIntent(timerType: .sleep, action: .start)) { // button view } // or let intent = TimerActionIntent() intent.timerType = timerType intent.action = .start Button(intent: intent) { // button view } and only execute when initialize TimerActionIntent without any parameters and @Parameter has the default value. e.g. Button(intent: TimerActionIntent()) { // button view } I have some logs in the Console app: default 17:51:27.626382+0800 linkd Accepting XPC connection from PID 39255 for service "com.apple.linkd.registry" default 17:51:27.637511+0800 WidgetsExtension Beginning PerformAction <<SB:788D850BBBC5>> default 17:51:27.637540+0800 WidgetsExtension Beginning InitializeAction <<SB:ACBC7A27CCBF>> default 17:51:27.637556+0800 WidgetsExtension [InitializeAction <<N:ACBC7A27CCBF>>] Found TimerActionIntent matching TimerActionIntent registered with AppManager default 17:51:27.637725+0800 WidgetsExtension Prepared timerType to TimerType(TimerType/0)) default 17:51:27.637744+0800 WidgetsExtension Prepared action to TimerAction(TimerAction/0)) default 17:51:27.637772+0800 WidgetsExtension Ending InitializeAction <<SE:ACBC7A27CCBF>> default 17:51:27.637795+0800 WidgetsExtension Beginning ResolveParameters <<SB:6C7CA02308AD>> default 17:51:27.639807+0800 WidgetsExtension Building resolver for parameter timerType<TimerType> = TimerType/0 default 17:51:27.640160+0800 WidgetsExtension Building resolver: EntityIdentifier → TimerType:TimerActionIntent:timerType default 17:51:27.640202+0800 WidgetsExtension Ending ResolveParameters <<SE:6C7CA02308AD>> default 17:51:27.640221+0800 WidgetsExtension Beginning NeedsDisambiguation <<SB:8E482F9CCCB0>> default 17:51:27.641328+0800 WidgetsExtension Ending NeedsDisambiguation <<SE:8E482F9CCCB0>> default 17:51:27.641344+0800 WidgetsExtension Ending PerformAction <<SE:788D850BBBC5>> error 17:51:27.642316+0800 chronod Perform action connection operation completed with error: Error Domain=LNActionExecutorErrorDomain Code=2010 "(null)" error 17:51:27.642774+0800 chronod Operation `<LNPerformActionConnectionOperation: 0x600002c4a180, identifier: F8FB77C5-7F8A-4670-BB8C-465DE4EAB6B8>` error Error Domain=LNActionExecutorErrorDomain Code=2010 "(null)" default 17:51:27.643358+0800 linkd Invalidated XPC connection from PID 39255 for service "com.apple.linkd.registry" I can't find any details about the error " Error Domain=LNActionExecutorErrorDomain Code=2010 "(null)"" The environment: Xcode: 16.4/26 beta 5 iOS: iOS Simulator 18.5, iOS Simulator 26, iPhone 16 Pro Max 18.6 macOS 15.6 Can anyone help me, please!
2
0
71
Aug ’25
What's the max duration for a live activity?
The docs are conflicting. https://developer.apple.com/documentation/activitykit/starting-and-updating-live-activities-with-activitykit-push-notifications#End-the-Live-Activity-with-a-custom-dismissal-date says: When you end a Live Activity, by default the Live Activity appears on the Lock Screen for up to four hours after it ends to allow people to glance at their phone to refer to the latest information. However here it says: https://developer.apple.com/documentation/activitykit/displaying-live-data-with-live-activities#Understand-constraints A Live Activity can be active for up to eight hours unless its app or a person ends it before this limit. After the eight-hour limit, the system automatically ends the Live Activity, and immediately removes it from the Dynamic Island. However, the Live Activity remains on the Lock Screen until a person removes it or for up to four additional hours before the system removes it — whichever comes first. As a result, a Live Activity remains on the Lock Screen for a maximum of 12 hours. So is it 4 hrs OR '8 for Dynamic Island vs 12 for Lock Screen'?
2
0
131
Aug ’25
Title and Subtitle in Control Widget on macOS Tahoe?
Hi 🙋 Has anybody gotten subtitles in macOS Tahoe Control Widgets to show up in their custom control widgets? Seems macOS is able to do it (see attached screenshot of the Bluetooth control widget), but my widget, which shows a title and subtitle on iOS, will only show the title on macOS. I tried all the different ControlWidgetButton init methods to no avail. I tried a VStack for my title and subtitle Texts, I tried just two Texts without a VStack, I tried the controlWidgetStatus and controlWidgetActionHint modifiers out of desperation... nothing worked. Any pointers much appreciated! Thank you, – Matthias
2
1
133
4w
Push notifcation-driven live activity not starting
Hi, I'm having this issue that I have have not been able to figure out as I've gone through a checklist and it seems I have everything in place, but im sending my pushToStartTokenUpdates token to a server and im able to test starting a live activity via CURL where it shows my push token going through and even my test payload but after a while I get this issue in my logs where it fails to find a live activity Push notifications are set up, im sending my token to APN and im even able to start live activities locally.
2
0
137
Sep ’25
Live Activity budget exceeded
When sending multiple push to start notifications to start a live activities in a short time frame, after around 10 pushes live activities are no longer being started. Device logs show the following entry: Push-to-start budget exceeded for com.att.tlv.myatt::pushToStart; not starting activity What can be done to be able to open more live activities via push-to-start in a short time frame (increase the push-to-start budget)? Can this be related to the development environment and it will not happen on production? NSSupportsLiveActivitiesFrequentUpdates is already set to YES
2
0
135
3w
Widget with Core Data guidance
I have an app that has a Core Data store for dates with descriptions that I'd like to present in a widget with countdown calculations. In the app I have a button that just equates an active calculation to the currently selected item in the database (using an EnvironmentObject). I gather I can't use this mechanism inside a widget, right? The user could put tons of items into the database - so I'm sure I don't want to have an editable widget allowing them to pick. I suppose I could create an intent and allow an independent entering from the app - but that seems rather user hostile since they've already entered it for the app - and I'm still trying to support iOS15 which doesn't support that. I did create an App Group and have the Core Data store available from within the widget, but I don't see how to allow the user to choose which date is active. I also want multiple widgets to be able to point to different dates. Any help would be appreciated. Thanks!
2
0
216
3h
WidgetKit memory issues only in iOS 18.3
I've been working on a new application and beta testing with TestFlight. When iOS 18.3 came out, my widgets stopped working due to using too much memory. I've been trying to debug for a while now, but not making much progress. Now that iOS 18.4 is out, I noticed the widgets are working again. I'm wondering if there was some change made in iOS 18.3 that was rolled back in iOS 18.4 that I'm not seeing in the iOS Release Notes etc? I haven't seen much in the Developer Forums, either. My concern is that perhaps Apple decided to make the 30MB Widget memory limit a "hard" limit, but then rolled it back, perhaps temporarily, so I'd like some clarity on the situation if possible. Otherwise, I did notice that it seemed as if all of my widgets were loaded at once, even if only one widget was installed, this boosting the memory usage significantly. If so, that might indicate that a bug was fixed in the Widget Provider system? In any case, I'd appreciate any information or advice on this. Thanks!
3
0
133
Apr ’25
Can't change iPhone watch app complication picker app name
I have an objective-c watch app and have added a swift widget style compilation to it and am having problems. The complication works fine but the name in the iPhone watch app complication picker stubbornly remains as the watchkit app name despite me trying various ways of changing it. Here are the various CF bundle name and display name values I am using: phone app values CFBundleIdentifier - com.Distribution-Systems-Associates.Tennis-Watch-v1 CFBundleName - $(PRODUCT_NAME) CFBundleDisplayName - Tennis Scorekeeper watchkit app CFBundleIdentifier - com.Distribution-Systems-Associates.Tennis-Watch-v1.watchkitapp CFBundleName - Tennis Scorekeeper CFBundleDisplayName - Tennis Scorekeeper WatchKit extension CFBundleIdentifier - com.Distribution-Systems-Associates.Tennis-Watch-v1.watchkitapp.watchkitextension CFBundleName - Tennis Scorekeeper CFBundleDisplayName - Tennis Scorekeeper __Watchkit complication __ CFBundleIdentifier - com.Distribution-Systems-Associates.Tennis-Watch-v1.watchkitapp.watchkitextension.Tennis-Watch-V1-Complication Changing the values in the complication doesn't seem to matter. Every other name in both my iPhone and watch apps are as expected. ChatGPT suggested that I try adding a localized name in the watchkit app but that didn't seem to do much of anything useful. I have run this though Chat quite a bit to see if I could get any accidental insights that way and while it has been interesting, it has also been not terribly helpful. I didn't post any of the complication code because that seems to be fine. However, I can do that if needed. The complication works as intended (starts the app). The various names everywhere else show up as intended. It's just that this one name refuses to be overridden. Thoughts?
3
0
128
May ’25
Maximise background update on WatchOS
I'm looking to maximise my Watch app's widget to be as up to date as possible. If we imagined the app was a simple step counter, and we wanted to display the users count as up to date as possible. We can conclude: We don't care about widget timelines beyond the current entry as we can't predict the future! We need to refresh the count as often as possible The refresh should be very quick with a straightforward HealthKit query, no networking or heavy work needed. We will assume the user has the complication/widget on their active Watch face. With the standard WidgetKit APIs we can expire the timeline after 15 minutes and in my experimentation a Watch app can usually update its widget timeline at that frequency if it's on the Watch face. I'm experimenting with two methods to try and improve refreshes further A user's step count might not have recently changed when the timeline update is called. I was therefore looking into the HealthKit enableBackgroundDelivery API (which requires the HealthKit Background Delivery entitlement to be enabled) to get updates limited to once an hour from a HKObserverQuery, I can then call the WidgetCenter.shared.reloadAllTimelines() from there. WatchOS also support the BGAppRefreshTaskRequest(identifier:"") and .backgroundTask(.appRefresh) APIs. I can request updates once every 15 minutes here too and then call the WidgetCenter.shared.reloadAllTimelines(). With option 1, this update opportunity is great as it will specifically update when there's new steps so even once an hour this would be helpful (A real shame to be limited to once an hour even if this used up WidgetKit standard reload budgets: FB13879817, FB11677132, FB10016177). But I can't determine if this update takes away one of the standard timeline expiration updates that already run 4 times an hour? Could I observe additional Health types to get additional updates? Do I need the Background Modes Capability as well as the HealthKit Background Delivery for this in Xcode or just the HealthKit one? With option 2, I can't find a suitable option in the (short) list of supported background modes in Xcode. Does not selecting any mean my app will get 0 refreshes from this route and so should not be implemented in my use case?
3
1
126
Jun ’25
Generating token using pushToStartTokenUpdates in terminated state
Pretty much the title. I am a noob in apple app development and currently starting it out. I got stuck in this. Can anyone let me know that how can i generate the token for starting live activity in terminated state? I have tried multiple times to find that this one is not working in terminated state. How can I overcome this? Is there any solution or workaround?
3
0
120
Jul ’25
How to opt out of tinting widget content on visionOS
During the WWDC Session called "Design widgets for visionOS" the presenter says: You can choose whether the background of your widget participates in tinting. If you opted out, for example to preserve a photo or illustration, make sure it still looks good alongside the selected color palette. Unfortunately, this session has no example code. Can someone point me to the correct way to do this? Is there a modifier we can use on views? (reposting this in the correct topic/subtopic)
3
0
141
Aug ’25
ManagedSettings doesn't block Live Activities in the Dynamic Island
When using the ManagedSettings API to block apps everything is blocked as expected (the app itself, Notifications, Live Activities on the Lock Screen etc) except for Compact Live Activities of those apps (that are shown in the Dynamic Island). I feel the expected behavior would be to block also the Compact Live Activities. Our use case: In Spoilerblock we want to prevent users from being exposed to spoilers before they've had time to watch for example a sports game. Current workaround: Right now the best we can do is to ask the user to disable Live Activities for apps that could expose results, to not risk being exposed to a spoiler.
3
0
36
Aug ’25
AppIntents not working in Release
We have some AppIntents we are POCing and when we make a Release build, they no longer appear in the system. These AppIntents live in a Framework compiled and linked with the core app. We believe that this is related to Mergable Libraries. We have confirmed that the meta data for the framework still contains a list of all of the actions and their mangled symbols. The mangled symbols however now live in the app binary (confirmed by building Release with DEBUG_INFORMATION_FORMAT = dwarf) If we move the AppIntent code into the app target, things once again work as expected. Is there a flag we need to set, or is moving the code into the app target the only workaround? Thank you!
3
0
254
Aug ’25
App group not working between iOS and watchOS
Hi everyone, I'm using an app group to share data between iOS and it's watch companion app. I ensured that is has the same identifier in Signing &amp; Capabilities and in the .entitlements files. Here is the UserDefaults part: class UserDefaultsManager { private let suitName = "group.com.sanjeevbalakrishnan.Test" public func saveItems(_ items: [ItemDTO]) { print("Save \(items.count) items to shared defaults") let defaults = UserDefaults(suiteName: suitName) let data = try? JSONEncoder().encode(items) defaults?.set(data, forKey: "items") } public func loadItems() -&gt; [ItemDTO] { let defaults = UserDefaults(suiteName: suitName) print(defaults) guard let data = defaults?.data(forKey: "items") else { print("watchOS received data is empty") return [] } let items = [ItemDTO].from(data: data) print("Load \(items.count) items from user defaults") return items } } For testing I called loadItems after saveItems on iOS app and it returned items. However, on watchOS app it always returns empty array. What do I need to consider? Thanks. Best regards Sanjeev
3
0
154
Sep ’25
iOS did not update all widgets of an app when the user press a button on a widget
Hello, I have an app in AppStore "Counter Widget". https://apps.apple.com/app/id1522170621 It allows you to add a widget to your homescreen/lockscreen to count anything. Everything works fine except for one scenario. iOS 18+ I create 2 or more widgets for one counter. For example, medium and small widgets. I click on the widget button to increase or decrease the value. The button in the widget uses Button(intent: AppIntent) to update the value and calls WidgetCenter.shared.reloadAllTimelines() to update the second widget for the same counter. For iOS 18 in this particular scenario, you don't even have to call the WidgetCenter.shared.reloadAllTimelines(). iOS already knows that there is a widget with the same INIntent settings and will update it itself. Both widgets are updated and show the new value. Everything is correct. Now on the homescreen I open the widget configuration for one of the widgets to change the INIntent for the widget. For example, i change the background to wallpaper. This is just a skin for the widget, and the widget is associated with the same counter value as before. As in (2), I click the widget button to increase or decrease the value. But now only one widget is updated. iOS ignores my call to WidgetCenter.shared.reloadAllTimelines() and does not update the second widget connected to the same counter. As I found, iOS, when I call WidgetCenter.shared.reloadAllTimelines() from the widget itself, updates other widgets only if INIntent is absolutely equal for them. Overriding isEqual for them did not help. That is, I cannot specify which fields from my INIntent can be ignored during such an update and consider that widgets are equal and need to be updated. Obviously iOS make this compare outside my code. The main problem is that when the user adds a widget to the lock screen and increases and decreases the value there. After that, he opens the home screen and the widget there is not synchronized with the value from the widget on the lock screen. How to solve this problem?
4
0
706
Apr ’25
Live Activity Update Not Working Consistently in the Background
Hi everyone, I’m working on implementing Live Activities in my app, and I’ve encountered an issue where the Live Activity updates work intermittently when the app is in the background. Sometimes they update correctly, but at other times, they don’t update at all, even though they should be running in the background. However, when the app is brought to the foreground, the updates happen correctly. A few things I’ve checked: The app is using ActivityKit to update the Live Activity with Activity.update(). I’ve enabled the necessary background modes in the Capabilities section. Is there a possibility that I’m hitting the system budget limit while experiencing this issue? If this is a limitation, how can I avoid it or manage this situation? Has anyone else faced this issue? Any advice or potential solutions would be greatly appreciated! Thank you!
4
0
501
Aug ’25
Can't load widget with a particular bundle id on Catalyst
Please note that the widgets sub forum is a 404: https://developer.apple.com/forums/post/question?community=1394020 I have a widget that works on iOS but doesn't work on Catalyst. The widget does not appear in the list of available widgets to install. It's related to the Bundle ID for the widget. If I use a fresh bundle ID the widget loads, but if I use the one I'm currently using for iOS it doesn't appear as available to install. To confirm it's related to the bundle ID I created a fresh project in xcode and recreated the behaviour. Any help greatly appreciated.
4
0
92
May ’25
Migrate Widgets from StaticConfiguration to IntentConfiguration
New features in WatchOS 26 with configurable widgets make it more important than ever that apps adopt IntentConfiguration options where applicable. I develop an app with an Apple Watch complication/widget on many many user's Watch faces around the world. I've completed updating my code to support WidgetKit and remove ClockKit. However, I face huge issues adding support for users to configure their widget/complications. If I update a widget to go from StaticConfiguration to IntentConfiguration, even when keeping the "kind" string the same, the widget disappears from the Watch face. This is an unacceptable user experience meaning I can't proceed with the migration. The problem is users will expect me to offer configuration in the Watch face soon for their widget/complication. Currently this process is done in a sub-optimal way in the app itself. A similar issue exists on iOS where the widget will just "freeze" indefinitely is migrated. This issue still occurs on the iOS 26 and WatchOS 26 betas. So how to move this forward. This has been discussed previously here: https://developer.apple.com/forums/thread/661247 I've mentioned it at WidgetKit labs I've filed feedback last year: FB13880020 I've filed feedback this year: FB18180368 It seems really important this gets fixed for developers to adopt these new features, is there any other migration route I'm missing or a workaround that would mitigate this seemingly big problem.
4
1
145
2w
Live Activity doesn't update as frequently as it should
I'm developing an app which will show the driver ETA and rendering the progress bar of the current ETA. Intuitively the backend server sends the push notification every 3 seconds through firebase cloud message service to APNS so that the device can refresh the dynamic island smoothly. But the live activity doesn't refresh as frequently as the backend service does. It should refresh every 3 seconds but it turns out like refresh 30 ~ 60 seconds, sometimes it didn't refresh at all. any body facing the same?
4
0
133
Aug ’25