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!
Widgets & Live Activities
RSS for tagDiscuss how to manage and implement Widgets & Live Activities.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
When we use AppIntents to configure WidgetKit complications, the description we provide in IntentRecommendation is ignored after applying a .watchface file that includes those intent configurations. In the Watch app, under Complications, the labels shown next to each slot do not match the actual complications on the face—they appear to be the first strings returned by recommendations() rather than the selected intent configuration.
Steps to Reproduce
Create an AppIntent used by a WidgetKit complication (e.g., .accessoryRectangular).
Provide multiple intent recommendations with distinct descriptions:
struct SampleIntent: AppIntent {
static var title: LocalizedStringResource = "Sample"
static var description = IntentDescription("Sample data")
@Parameter(title: "Mode") var mode: String
static func recommendations() -> [IntentRecommendation<Self>] {
[
.init(intent: .init(mode: "A"), description: "Complication A"),
.init(intent: .init(mode: "B"), description: "Complication B"),
.init(intent: .init(mode: "C"), description: "Complication C")
]
}
func perform() async throws -> some IntentResult { .result() }
}
Add two of these complications to a Modular Duo face (or any face that supports multiple slots), each with different intent configurations (e.g., A in one slot, B in another).
Export/share the face to a .watchface file and apply it on another device.
Open the Watch app → the chosen face → Complications.
Expected
Each slot’s label in Complications reflects the specific intent configuration on the face (e.g., “Complication A”, “Complication B”), matching what the complication actually renders.
Actual
The labels under Complications do not match the visible complications. Instead, the strings shown look like the first N items from recommendations(), regardless of which configurations are used in each slot.
Notes
The complications themselves render correctly on-watch; the issue is the names/labels displayed in the Watch app UI after applying a .watchface.
Filed Feedback: FB20915258
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Tags:
watchOS
Watch Complications
WidgetKit
App Intents
Hey,
I successfully set my app to use alarm kit, alarm is showing up and everything, but I noticed that the sound I created (mp3 files, less than 30 sec each) only plays once, does not repeat itself. Is that intended?
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Hi there,
I'm adding a new widget using the new WidgetConfigurationIntent which takes a number of parameters, including one which conforms to AppEntity. It is defined as an optional.
When the user is configuring the widget, after one of the suggested entities is chosen, there is no way to return to a state where this value is nil. Is this possible? I'd like the user to be able to select "None" for this parameter. For now, I'm using a bool to determine whether the AppEntity parameter is used.
Thanks!
I noticed that with iOS 18, when adding a widget to the Control Center, there is now some "grouping system". I'm interested in the Capture group, which contains native widgets from Apple as well as third party apps like Instagram and Blackmagic cam, widgets in this group open the camera. My widget also opens the camera in my app, how can I add it to this group?
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Tags:
SwiftUI
WidgetKit
App Intents
Live Activity Start Token not generating after certain days of usage. We have implemented Live Activity feature where the initial activity is launched by our backend. But to start that first live activity I need push to start token which is generating for few days but all of sudden after certain days it stops generating. Currently we are in development phase so we test it on multiple devices and multiple time we are doing install and uninstall.
STEPS TO REPRODUCE
Install the app
Start token gets generated which is sent to our server
After certain duration server sends the first live activity using that token
user opens the app then we receive the updated token and send that token to server
server uses that updated token to further update the live activity.
All this works fine. But after a week of usage we are observing that we stop getting start token from APNS. Not sure where exactly the thing is breaking. We have tried with different devices and different bundle identifiers but behaviour is same for all.
func generateStartToken() {
Task.detached { [weak self] in
guard let self else { return }
await self.observeActivityPushTokenAndState()
for await data in ActivityKit.Activity<LiveActivityAttribute>.pushToStartTokenUpdates {
let token = data.map { String(format: "%02x", $0) }.joined()
print("Activity Start token: ", token)
}
}
}
func observeActivityPushTokenAndState() {
Task.detached {
for await activity in ActivityKit.Activity<LiveActivityAttribute>.activityUpdates {
Task {
for await tokenData in activity.pushTokenUpdates {
let updatedToken = tokenData.map { String(format: "%02x", $0) }.joined()
print("Activity Update token: ", updatedToken)
}
}
Task {
for await content in activity.contentUpdates {
let updatedContent = content.state
print("Activity Updated: ", updatedContent)
}
}
}
}
}
I have a question about how a watch widget can access HealthKit data. Does it, as the large model mentioned, share data through an App Group, or does it directly access the HealthStore?
Hi, I have a class project I am working on (with a due date tomorrow, unfortunately RIP to me). But I have made my project about adding accessibility to a Unity game. I've successfully added apple unity core and accessibility plugins to my project, and my project builds. But I have simple text nodes and buttons and they aren't accessible with voiceover once I build/export my game and test. I am only building for MacOS right now (for the assignment).
I don't have too much experience with Unity, but I am relatively experienced with accessibility (even formerly an intern and contractor at Apple for accessibility). So I wonder if I am just using Unity incorrectly? Perhaps I've done something to my build process (or haven't done something I should)? I've attached a photo of what my dev environment looks like in Unity, I've focused a text node (on the left) and on the right are my AccessibilityNode settings.
Any help would be awesome, even if I don't make my deadline tomorrow... :*(
Project repo is here, if it is helpful: https://github.com/frankelavsky/PGD_final_project
Thanks!
I am seeing a really weird behavior with Live Activities. The Live Activity is always appearing on the simulator. However the Live Activity is only appearing on my physical device when there is no other widget in the widget bundle shown below.
@main
struct HoerspielWidgetsBundle: WidgetBundle {
var body: some Widget {
// Uncomment the line below and the Live Activity will no longer appear
// UpNextWidget()
PlaybackLiveActivity()
}
}
Annotating that var with @WidgetBundle has no effect.
There are no logs indicating an error, the function to request a Live Activity does not throw and the status of the activity is active.
Both the widget and the Live Activity are working fine otherwise. NSSupportsLiveActivities is set to true in the correct Info.plist file. I am not running any beta software and the physical iPhone is on the newest version (iOS 18.5). Using the template when adding a new target in Xcode, I was able to set up a similar app where the Live Activity works as expected.
I am really at a loss here which additional information I should provide or how this issue can be resolved.
Thank you for your help.
Hello forum,
I want to keep my app running in the background after user swaps up, for the purpose of workout tracking.
start up the task and continuously receipt GPS updates
process the location data
show the data on a live activity
Two examples
Strava
paddlelogger
Question:
Does this mean, these two apps would just pause when the .backgroundTimeRemaining becomes 0?
How does a workout app "work" in background mode, do I need to handle budget running out?
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Tags:
Core Location
Maps and Location
Background Tasks
Hi, I’m using SwiftData with an @Observable DatabaseManager class that is shared between my app and a widget. This class is located inside a Swift package and looks roughly like this:
public final class DatabaseManager {
public static let shared = DatabaseManager()
private init() {
let groupID = "group.com.yourcompany.myApp"
let config = ModelConfiguration(groupContainer: .identifier(groupID))
let c = try! ModelContainer(for: MyModel.self, configurations: config)
self.container = c
self.modelContext = c.mainContext
}
public private(set) var container: ModelContainer
public private(set) var modelContext: ModelContext
}
In the main app, I inject the container and context like this:
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.modelContainer(DatabaseManager.shared.container)
.modelContext(DatabaseManager.shared.modelContext)
}
}
}
Both the widget and the main app import the same package, and both use DatabaseManager.shared for reading and writing objects.
The problem:
When the widget updates an object using an AppIntent, the change is not reflected in the main app unless I fully terminate and relaunch it. If I just bring the app back to the foreground, it still shows stale data.
Is there a recommended way to make the main app observe or reload SwiftData changes that were made in the widget (via the same shared app group and container)? I’m already using .modelContainer(...) and .modelContext(...) in the app, and everything else works fine — it’s just the syncing that doesn’t happen unless I force-relaunch the app.
Thanks!
Hello,
I am trying to create a Home Screen widget for iOS that displays device usage statistics — similar to the built-in Screen Time widget Apple provides. The goal is to show the average device usage for a specified period (daily, weekly, or monthly) and optionally include a comparison with the previous period.
I noticed that Apple’s own Screen Time widget presents such information. However, after reviewing the public documentation, I could not find any available API that allows a developer to create a similar experience.
To explore possible alternatives, I implemented a SwiftUI view inside a com.apple.deviceactivityui.report-extension using the Family Controls and Device Activity frameworks. The view works fine within the main app and the report extension context, but when I attempted to use the same view in a WidgetKit extension, I received an error at runtime. This suggests that views from com.apple.deviceactivityui.report-extension are not usable inside widgets, which I understand may be due to sandboxing or limitations of how the extension points are designed.
So far, I’ve found no way to access cumulative or average usage data (screen time, app usage, etc.) from system APIs that can be shown in a widget context. My understanding is that Family Controls and Device Activity frameworks allow observing ongoing activity and building usage reports inside the app, but do not provide access to the same historical or summarized data that Apple’s own widgets display.
Could you please confirm:
Whether there is any supported way to access average device usage (screen time) data for use in a widget?
If not, is this an intentional limitation due to privacy concerns, or is there a roadmap for exposing such APIs in the future?
Are there any APIs or entitlements that could allow similar functionality via WidgetKit?
Thank you for your time and support.
Best regards,
I was very excited to see the addition of push notifications for widgets. However upon further inspection, the way it is implemented seems too limiting for real life apps.
I have an app for time tracking with my own backend. The app syncs with my backend in the main executable (main target). My widgets are more lightweight as they only access data in the shared app container, but they don't perform sync with the server directly to avoid race conditions with the main app.
I was under the impression that the general direction of the platform is to be doing most things in the main app target (also App Intents work that way for the most part), so the fact that the WidgetPushHandler just calls the widget's method to reload the timeline is very unfortunate. In an ideal scenario I also need the main app to be 'woken up' to perform the sync with the server, and once that's done I'd update the widget's timeline and where I would just read data from the shared app container.
So, my questions are:
What is the recommended way of updating the widgets when this push notification arrives in the case that the main app target needs to perform the sync first?
Is there any way how to detect that the method
func timeline(for configuration: InteractiveTrackingWidgetConfigurationAppIntent, in context: Context)
was called as a result of the push notification being received?
Can I somehow schedule a background task from the widget's reloadTimeline() function?
How can I get the push token later, in case that I don't save it right away the first time the WidgetPushHandler's pushTokenDidChange() is called?
Thank you for your work on this and hopefully for your answers.
FB19356256
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!
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
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'?
LiveActivity using colorScheme to adapt to dark mode in iOS 26 system does not work
The system keeps returning. mark, unable to switch
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?
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
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.
Topic:
App & System Services
SubTopic:
Widgets & Live Activities
Tags:
User Notifications
ActivityKit
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