WidgetKit

RSS for tag

Show relevant, glanceable content from your app on iOS and iPadOS Home Screen and Lock Screen, macOS Desktop, Apple Watch Smart Stack and Complications, and in StandBy mode on iPhone.

Posts under WidgetKit tag

150 Posts

Post

Replies

Boosts

Views

Activity

Can You Debug a Widget on Actual Device?
I'm working on an iOS app with a Widget. I am able to display the Widget on the iPhone 16 Pro Simulator. It doesn't appear on iPad mini 6th gen., though. Anyway, I want to make sure that it works on an actual device. If I try to add the Widget to the Home Screen, I cannot find it in the search list on iPhone XR and iPad 9th gen. If I set the target to that of the widget, Xcode gives me the following error. SendProcessControlEvent:toPid: encountered an error: Error Domain=com.apple.dt.deviceprocesscontrolservice Code=8 "Failed to show Widget 'some bundle ID' error: … I hope that's not a sign of trouble. So how do you debug a Widget on an Actual Device? I've read some topics like this one here. Thanks.
2
0
124
May ’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
284
May ’25
Unable to launch + Attach to Mac Widget (Sonoma + Xcode 15)
Attempting to launch a widget in Debug mode on Sonoma from Xcode 15 is failing with the following message: attach failed (Not allowed to attach to process. Look in the console messages (Console.app), near the debugserver entries, when the attach failed. The subsystem that denied the attach permission will likely have logged an informative message about why it was denied.) Looking in console I see this message: macOSTaskPolicy: (com.apple.debugserver) may not get the task control port of (MacGalleryWidget) (pid: 1851): (MacGalleryWidget) is hardened, (MacGalleryWidget) doesn't have get-task-allow, (com.apple.debugserver) is a declared debugger(com.apple.debugserver) is not a declared read-only debugger What Xcode settings should I be looking at to rectify this? I suspect I may have something that's out of whack.
1
4
1.2k
May ’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
321
May ’25
Lock widget for pro-users
Hi, I have added widgets to my iOS app and I would like to make this feature only accessible to "pro" users that have made a non-consumable in-app purchase. Currently, I am doing the following: I store an "isUnlocked" property in the Keychain after the purchase is made I read data to be displayed in the widget and here I also query the Keychain and store whether the widget is unlocked I have no refresh policy, but only change the widget data on a significant time change a different view is displayed when the app is locked Some dummy code snippets: func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) { &#9;&#9;let entry = readContents() &#9;&#9;let timeline = Timeline(entries: [entry], policy: .never) &#9;&#9;completion(timeline) } struct WidgetEntryView: View { &#9;&#9;let entry: Provider.Entry     @Environment(\.widgetFamily) var family     @ViewBuilder     var body: some View {         switch family {         case .systemSmall:             if !entry.isUnlocked {                 LockedWidgetView()             } else if let event = entry.event {                 SmallWidgetEventView(event: event)             } else {                 NoDataWidgetView()             } ... func applicationSignificantTimeChange(_ application: UIApplication) { &#9;&#9;if #available(iOS 14.0, *) { &#9;&#9;&#9;&#9;WidgetCenter.shared.reloadAllTimelines() &#9;&#9;} ... However, 2 unexpected things happen: the view is refreshed intraday (not only at midnight i.e. at significant time change) sometimes the LockedWidgetView is displayed. Especially the latter is problematic, because it gives false information to a user that has already made the in-app purchase. How can I achieve my goal of only displaying info when the user has made the in-app purchase? Thanks in advance. P.S. Although it would not have my preference, I would also find it acceptable if the widget is only shown as option to add once the purchase is made. In other words, I was considering changing the Widget itself: struct MyWidget: Widget {     private var supportedFamilies: [WidgetFamily] = isUnlocked() ? [.systemSmall, .systemMedium] : [] but I believe I cannot re-initialise the widget from the app when the user makes the in-app purchase, because the only refresh option that I have is WidgetCenter.shared.reloadAllTimelines()
7
0
3.8k
May ’25
Help getting elements from SwiftData in AppIntent for widget
Hello, I am trying to get the elements from my SwiftData databse in the configuration for my widget. The SwiftData model is the following one: @Model class CountdownEvent { @Attribute(.unique) var id: UUID var title: String var date: Date @Attribute(.externalStorage) var image: Data init(id: UUID, title: String, date: Date, image: Data) { self.id = id self.title = title self.date = date self.image = image } } And, so far, I have tried the following thing: AppIntent.swift struct ConfigurationAppIntent: WidgetConfigurationIntent { static var title: LocalizedStringResource { "Configuration" } static var description: IntentDescription { "This is an example widget." } // An example configurable parameter. @Parameter(title: "Countdown") var countdown: CountdownEntity? } Countdowns.swift, this is the file with the widget view struct Provider: AppIntentTimelineProvider { func placeholder(in context: Context) -> SimpleEntry { SimpleEntry(date: Date(), configuration: ConfigurationAppIntent()) } func snapshot(for configuration: ConfigurationAppIntent, in context: Context) async -> SimpleEntry { SimpleEntry(date: Date(), configuration: configuration) } func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline<SimpleEntry> { var entries: [SimpleEntry] = [] // Generate a timeline consisting of five entries an hour apart, starting from the current date. let currentDate = Date() for hourOffset in 0 ..< 5 { let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)! let entry = SimpleEntry(date: entryDate, configuration: configuration) entries.append(entry) } return Timeline(entries: entries, policy: .atEnd) } // func relevances() async -> WidgetRelevances<ConfigurationAppIntent> { // // Generate a list containing the contexts this widget is relevant in. // } } struct SimpleEntry: TimelineEntry { let date: Date let configuration: ConfigurationAppIntent } struct CountdownsEntryView : View { var entry: Provider.Entry var body: some View { VStack { Text("Time:") Text(entry.date, style: .time) Text("Title:") Text(entry.configuration.countdown?.title ?? "Default") } } } struct Countdowns: Widget { let kind: String = "Countdowns" var body: some WidgetConfiguration { AppIntentConfiguration(kind: kind, intent: ConfigurationAppIntent.self, provider: Provider()) { entry in CountdownsEntryView(entry: entry) .containerBackground(.fill.tertiary, for: .widget) } } } CountdownEntity.swift, the file for the AppEntity and EntityQuery structs struct CountdownEntity: AppEntity, Identifiable { var id: UUID var title: String var date: Date var image: Data var displayRepresentation: DisplayRepresentation { DisplayRepresentation(title: "\(title)") } static var defaultQuery = CountdownQuery() static var typeDisplayRepresentation: TypeDisplayRepresentation = "Countdown" init(id: UUID, title: String, date: Date, image: Data) { self.id = id self.title = title self.date = date self.image = image } init(id: UUID, title: String, date: Date) { self.id = id self.title = title self.date = date self.image = Data() } init(countdown: CountdownEvent) { self.id = countdown.id self.title = countdown.title self.date = countdown.date self.image = countdown.image } } struct CountdownQuery: EntityQuery { typealias Entity = CountdownEntity static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Countdown Event") static var defaultQuery = CountdownQuery() @Environment(\.modelContext) private var modelContext // Warning here: Stored property '_modelContext' of 'Sendable'-conforming struct 'CountdownQuery' has non-sendable type 'Environment<ModelContext>'; this is an error in the Swift 6 language mode func entities(for identifiers: [UUID]) async throws -> [CountdownEntity] { let countdownEvents = getAllEvents(modelContext: modelContext) return countdownEvents.map { event in return CountdownEntity(id: event.id, title: event.title, date: event.date, image: event.image) } } func suggestedEntities() async throws -> [CountdownEntity] { // Return some suggested entities or an empty array return [] } } CountdownsManager.swift, this one just has the function that gets the array of countdowns func getAllEvents(modelContext: ModelContext) -> [CountdownEvent] { let descriptor = FetchDescriptor<CountdownEvent>() do { let allEvents = try modelContext.fetch(descriptor) return allEvents } catch { print("Error fetching events: \(error)") return [] } } I have installed it in my phone and when I try to edit the widget, it doesn't show me any of the elements I have created in the app, just a loading dropdown for half a second: What am I missing here?
0
0
188
Apr ’25
Live Activity animate without updating data
Is it actually possible to display animation (even a simple one) on Live Activity? But on these cases: The main app is terminated - of course, I know I can use the main app to keep updating the Live Activity to make simple animations work, but in this case, the main app is killed. Live Activity data is not updating - I also understand that the Live Activity can perform animations when its data is being update via push notification or other means, but the current case is the data is not being updated. I’ve tried several ways to achieve this, but nothing seems to work. Just when I was about to give up, I found this video from Apple’s official channel: https://www.youtube.com/watch?v=m6WMwSj_EbA At 4:14 in this video, you can see the text "Locating Driver" with the breathing animation. Could someone please help me understand how to implement that kind of animation in a Live Activity when: The main app is not running, and The Live Activity data is not updating?
0
0
153
Apr ’25
Can You Debug a Widget on Actual Device?
I'm working on an iOS app with a Widget. I am able to display the Widget on the iPhone 16 Pro Simulator. It doesn't appear on iPad mini 6th gen., though. Anyway, I want to make sure that it works on an actual device. If I try to add the Widget to the Home Screen, I cannot find it in the search list on iPhone XR and iPad 9th gen. If I set the target to that of the widget, Xcode gives me the following error. SendProcessControlEvent:toPid: encountered an error: Error Domain=com.apple.dt.deviceprocesscontrolservice Code=8 "Failed to show Widget 'some bundle ID' error: … I hope that's not a sign of trouble. So how do you debug a Widget on an Actual Device? I've read some topics like this one here. Thanks.
Replies
2
Boosts
0
Views
124
Activity
May ’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?
Replies
3
Boosts
0
Views
284
Activity
May ’25
Unable to launch + Attach to Mac Widget (Sonoma + Xcode 15)
Attempting to launch a widget in Debug mode on Sonoma from Xcode 15 is failing with the following message: attach failed (Not allowed to attach to process. Look in the console messages (Console.app), near the debugserver entries, when the attach failed. The subsystem that denied the attach permission will likely have logged an informative message about why it was denied.) Looking in console I see this message: macOSTaskPolicy: (com.apple.debugserver) may not get the task control port of (MacGalleryWidget) (pid: 1851): (MacGalleryWidget) is hardened, (MacGalleryWidget) doesn't have get-task-allow, (com.apple.debugserver) is a declared debugger(com.apple.debugserver) is not a declared read-only debugger What Xcode settings should I be looking at to rectify this? I suspect I may have something that's out of whack.
Replies
1
Boosts
4
Views
1.2k
Activity
May ’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.
Replies
4
Boosts
0
Views
321
Activity
May ’25
Lock widget for pro-users
Hi, I have added widgets to my iOS app and I would like to make this feature only accessible to "pro" users that have made a non-consumable in-app purchase. Currently, I am doing the following: I store an "isUnlocked" property in the Keychain after the purchase is made I read data to be displayed in the widget and here I also query the Keychain and store whether the widget is unlocked I have no refresh policy, but only change the widget data on a significant time change a different view is displayed when the app is locked Some dummy code snippets: func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) { &#9;&#9;let entry = readContents() &#9;&#9;let timeline = Timeline(entries: [entry], policy: .never) &#9;&#9;completion(timeline) } struct WidgetEntryView: View { &#9;&#9;let entry: Provider.Entry     @Environment(\.widgetFamily) var family     @ViewBuilder     var body: some View {         switch family {         case .systemSmall:             if !entry.isUnlocked {                 LockedWidgetView()             } else if let event = entry.event {                 SmallWidgetEventView(event: event)             } else {                 NoDataWidgetView()             } ... func applicationSignificantTimeChange(_ application: UIApplication) { &#9;&#9;if #available(iOS 14.0, *) { &#9;&#9;&#9;&#9;WidgetCenter.shared.reloadAllTimelines() &#9;&#9;} ... However, 2 unexpected things happen: the view is refreshed intraday (not only at midnight i.e. at significant time change) sometimes the LockedWidgetView is displayed. Especially the latter is problematic, because it gives false information to a user that has already made the in-app purchase. How can I achieve my goal of only displaying info when the user has made the in-app purchase? Thanks in advance. P.S. Although it would not have my preference, I would also find it acceptable if the widget is only shown as option to add once the purchase is made. In other words, I was considering changing the Widget itself: struct MyWidget: Widget {     private var supportedFamilies: [WidgetFamily] = isUnlocked() ? [.systemSmall, .systemMedium] : [] but I believe I cannot re-initialise the widget from the app when the user makes the in-app purchase, because the only refresh option that I have is WidgetCenter.shared.reloadAllTimelines()
Replies
7
Boosts
0
Views
3.8k
Activity
May ’25
widget can access HealthKit data?
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?
Replies
2
Boosts
0
Views
229
Activity
Apr ’25
Question about transparent widget background
Hi, I've seen some apps that can have the widget background truly transparent ( not screenshot, code-level transparent) How did they do that? Is that allowed to publish in App Store?
Replies
1
Boosts
1
Views
110
Activity
Apr ’25
Help getting elements from SwiftData in AppIntent for widget
Hello, I am trying to get the elements from my SwiftData databse in the configuration for my widget. The SwiftData model is the following one: @Model class CountdownEvent { @Attribute(.unique) var id: UUID var title: String var date: Date @Attribute(.externalStorage) var image: Data init(id: UUID, title: String, date: Date, image: Data) { self.id = id self.title = title self.date = date self.image = image } } And, so far, I have tried the following thing: AppIntent.swift struct ConfigurationAppIntent: WidgetConfigurationIntent { static var title: LocalizedStringResource { "Configuration" } static var description: IntentDescription { "This is an example widget." } // An example configurable parameter. @Parameter(title: "Countdown") var countdown: CountdownEntity? } Countdowns.swift, this is the file with the widget view struct Provider: AppIntentTimelineProvider { func placeholder(in context: Context) -> SimpleEntry { SimpleEntry(date: Date(), configuration: ConfigurationAppIntent()) } func snapshot(for configuration: ConfigurationAppIntent, in context: Context) async -> SimpleEntry { SimpleEntry(date: Date(), configuration: configuration) } func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline<SimpleEntry> { var entries: [SimpleEntry] = [] // Generate a timeline consisting of five entries an hour apart, starting from the current date. let currentDate = Date() for hourOffset in 0 ..< 5 { let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)! let entry = SimpleEntry(date: entryDate, configuration: configuration) entries.append(entry) } return Timeline(entries: entries, policy: .atEnd) } // func relevances() async -> WidgetRelevances<ConfigurationAppIntent> { // // Generate a list containing the contexts this widget is relevant in. // } } struct SimpleEntry: TimelineEntry { let date: Date let configuration: ConfigurationAppIntent } struct CountdownsEntryView : View { var entry: Provider.Entry var body: some View { VStack { Text("Time:") Text(entry.date, style: .time) Text("Title:") Text(entry.configuration.countdown?.title ?? "Default") } } } struct Countdowns: Widget { let kind: String = "Countdowns" var body: some WidgetConfiguration { AppIntentConfiguration(kind: kind, intent: ConfigurationAppIntent.self, provider: Provider()) { entry in CountdownsEntryView(entry: entry) .containerBackground(.fill.tertiary, for: .widget) } } } CountdownEntity.swift, the file for the AppEntity and EntityQuery structs struct CountdownEntity: AppEntity, Identifiable { var id: UUID var title: String var date: Date var image: Data var displayRepresentation: DisplayRepresentation { DisplayRepresentation(title: "\(title)") } static var defaultQuery = CountdownQuery() static var typeDisplayRepresentation: TypeDisplayRepresentation = "Countdown" init(id: UUID, title: String, date: Date, image: Data) { self.id = id self.title = title self.date = date self.image = image } init(id: UUID, title: String, date: Date) { self.id = id self.title = title self.date = date self.image = Data() } init(countdown: CountdownEvent) { self.id = countdown.id self.title = countdown.title self.date = countdown.date self.image = countdown.image } } struct CountdownQuery: EntityQuery { typealias Entity = CountdownEntity static var typeDisplayRepresentation = TypeDisplayRepresentation(name: "Countdown Event") static var defaultQuery = CountdownQuery() @Environment(\.modelContext) private var modelContext // Warning here: Stored property '_modelContext' of 'Sendable'-conforming struct 'CountdownQuery' has non-sendable type 'Environment<ModelContext>'; this is an error in the Swift 6 language mode func entities(for identifiers: [UUID]) async throws -> [CountdownEntity] { let countdownEvents = getAllEvents(modelContext: modelContext) return countdownEvents.map { event in return CountdownEntity(id: event.id, title: event.title, date: event.date, image: event.image) } } func suggestedEntities() async throws -> [CountdownEntity] { // Return some suggested entities or an empty array return [] } } CountdownsManager.swift, this one just has the function that gets the array of countdowns func getAllEvents(modelContext: ModelContext) -> [CountdownEvent] { let descriptor = FetchDescriptor<CountdownEvent>() do { let allEvents = try modelContext.fetch(descriptor) return allEvents } catch { print("Error fetching events: \(error)") return [] } } I have installed it in my phone and when I try to edit the widget, it doesn't show me any of the elements I have created in the app, just a loading dropdown for half a second: What am I missing here?
Replies
0
Boosts
0
Views
188
Activity
Apr ’25
Live Activity animate without updating data
Is it actually possible to display animation (even a simple one) on Live Activity? But on these cases: The main app is terminated - of course, I know I can use the main app to keep updating the Live Activity to make simple animations work, but in this case, the main app is killed. Live Activity data is not updating - I also understand that the Live Activity can perform animations when its data is being update via push notification or other means, but the current case is the data is not being updated. I’ve tried several ways to achieve this, but nothing seems to work. Just when I was about to give up, I found this video from Apple’s official channel: https://www.youtube.com/watch?v=m6WMwSj_EbA At 4:14 in this video, you can see the text "Locating Driver" with the breathing animation. Could someone please help me understand how to implement that kind of animation in a Live Activity when: The main app is not running, and The Live Activity data is not updating?
Replies
0
Boosts
0
Views
153
Activity
Apr ’25
How to get the ControlWidget installed by user
Is there any way to obtain the ControlWidget installed by user, I use WidgetCenter.shared.getCurrentConfigurations cannot work
Replies
0
Boosts
0
Views
156
Activity
Apr ’25