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

200 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

ControlWidgetToggle state when parent app is terminated
I have programmed a ControlWidgetToggle which controls a recording state in our main app, that can be on (recording) or off (not recording). The recording can also be controlled from inside the main app, and there we call ControlCenter.shared.reloadControls(ofKind: "") to update the ControlWidgetToggle state when the recording state changes. Now this all works great, except for the situation in which the user terminates the app (for example using the app switcher screen). Then of course the recording will stop. I however have no idea how to update the state of the ControlWidgetToggle in this case, it will stay in the recording state since it does not know that the recording has been stopped. The applicationWillTerminate delegate method of the AppDelegate will not be called in such a case. Does someone has an idea how to update the state of the ControlWidgetToggle once the parent app has been terminated?
1
0
237
Sep ’24
AppIntent - Widget & ControlWidget
Hey all, iOS 18 - RC I have an app that supports both Widgets and ControlWidget, which resides on the same AppIntent. The following sync works fine when any action is taken on any of the three players - App - Widget - both directions - works as expected App - Control Widget - both directions - works as expected However - Widget - ControlWidget - the UI not always sync in real time (the values are ok) So if for instance I increase a counter on the widget from 1 to 2, the comtrolwidget will still show 1, but if I tap it, it will increase to 3. For any update/action taken on the AppInten, I call - WidgetCenter.shared.reloadAllTimelines() ControlCenter.shared.reloadAllControls() Any idea how to ensure this sync? Thanks a lot! Dudi
1
0
383
Sep ’24
Open specific screen in App Delegate after iOS 18 Control Center widget is tapped (failed to open URL)
I have created an iOS 18 Control Center Widget that launches my app. However I am not able to detect it in AppDelegate.swift. I have created custom scheme funRun://beginRun in Target => Info => URL Types URL Types setup in Xcode This method in AppDelegate.swift does not fire at all and I get this error in console: Failed to open URL runFun://beginRun: Error Domain=NSOSStatusErrorDomain Code=-10814 "(null)" UserInfo={_LSLine=279, _LSFunction=-[_LSDOpenClient openURL:fileHandle:options:completionHandler:]}`` ` func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { // this does not fire print("Scheme \(url.scheme)") print("Host \(url.host)") return true }` I tried this answer to no avail: iOS 18 Control Widget that opens a URL Even adding EnvironmentValues().openURL(url) as suggested here did not help. @MainActor func perform() async throws -> some IntentResult & OpensIntent { let url = URL(string: "funRun://beginRun")! EnvironmentValues().openURL(url) return .result(opensIntent: OpenURLIntent(url)) } Here is my extension code: My goal is to detect the url string from the request, so I can decide which screen to launch from AppDelegate's open url method. When I test this with iOS 18 RC it does not work either in simulator or on real device import AppIntents import SwiftUI import WidgetKit @available(iOS 18.0, watchOS 11.0, macOS 15.0, visionOS 2.0, *) struct StartRunControl: ControlWidget { var body: some ControlWidgetConfiguration { StaticControlConfiguration( kind: "name.funRun.StartRun", provider: Provider() ) { value in ControlWidgetButton("Hello", action: MyIntent()) { hi in Label("Start", systemImage: "sun.min.fill") } } .displayName("Start run") .description("Opens a run screen.") } } @available(iOS 18.0, watchOS 11.0, macOS 15.0, visionOS 2.0, *) extension StartRunControl { struct Provider: ControlValueProvider { var previewValue: Bool { false } func currentValue() async throws -> Bool { let isRunning = true // Check if the timer is running return isRunning } } } @available(iOS 18.0, watchOS 11.0, macOS 15.0, visionOS 2.0, *) struct MyIntent: AppIntent { static let title: LocalizedStringResource = "My Intent" static var openAppWhenRun: Bool = true init() {} @MainActor func perform() async throws -> some IntentResult & OpensIntent { let url = URL(string: "funRun://beginRun")! EnvironmentValues().openURL(url) return .result(opensIntent: OpenURLIntent(url)) } } I even checked info.plist and it seems okay. <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleTypeRole</key> <string>Editor</string> <key>CFBundleURLName</key> <string>beginRun</string> <key>CFBundleURLSchemes</key> <array> <string>funRun://beginRun</string> </array> </dict> </array> Does anyone know where the problem might be? Thanks!
1
0
510
Sep ’24
Restricting available units for a Measurement<UnitDuration> @Parameter
Hello, I'm preparing my app Tameno for iOS 18, adding a couple of Control Center widgets. One of them allows users to select their favorite interval. But in the context of my app, only seconds and minutes make sense as a unit value - I don't need milli-pseconds, nor hours. Is there a way restrict these available options that come from a ControlConfigurationIntent? @available(iOS 18.0, iOSApplicationExtension 18.0, *) struct TamenoFavoriteIntervalControlWidgetSetupIntent : ControlConfigurationIntent { static let title: LocalizedStringResource = "cw_FavoriteIntervalSetup" static let isDiscoverable: Bool = false @Parameter(title: "cw_IntervalParameter", defaultValue: 5.0, defaultUnit: .seconds, supportsNegativeNumbers: false) var interval: Measurement<UnitDuration>? @MainActor func perform() async throws -> some IntentResult { .result() } } I am able to restrict it just to seconds or minutes only (by adding unit: .seconds, or unit: .minutes to the @Parameter setup), but I'd really like to offer both. Thank you, Matthias
3
0
353
Sep ’24
How to create a custom TimeDataSource?
Hello. I am working with the iOS 18b8 and Xcode 16b6 betas, updating a Live Activity Widget to adopt the new FormatStyle variants of the SwiftUI Text views. We used to use: Text(workoutStartDate, style: .relative) and it seems with iOS 18 we can replace it with: Text(workoutStartDate, format: .relative(presentation: .numeric, unitsStyle: .wide)) The former code would auto-increment, allowing a user to look at their Live Activity and see the duration of their workout so far ticking by. The new code does provide a nice relative duration string, but it doesn't auto-increment in the Live Activity's View – I need that functionality. I also updated other Texts in the Live Activity's View to adopt the .timer and .stopwatch FormatStyles. Those auto-increment and update no problem – once I realized I needed to provide a TimeDataSource<Date>.currentDate and not a simple Date. But in this .relative case, there is no auto-incrementing, and I'm guessing it may be due to providing a Date (workoutStartDate) and not a TimeDataSource<Date> as TimeDataSource seems to be the magic to make the Text auto-increment (or it's possible this format simply doesn't support auto-increment? bummer if so since the prior way did). How can I have a TimeDataSource<Date> that vends my arbitrary date (workoutStartDate)? I dug around, didn't find anything, but I wouldn't be surprised if I was overlooking something. PS: I have tried other approaches to solve this, such as simply using a .timer or .stopwatch format. That would change the under experience under iOS 18, and we think degrade it (the relative textual representation is nicer and provides distinction from the .timer also in the same View). We could keep the former approach, despite the minor layout issues under iOS 18. I have considered additional approaches as well – and am totally open to more! Here tho, I am truly curious how one might provide a custom TimeDataSource anchored at a date we provide (perhaps dynamically). Thank you.
1
1
299
3w
Updating control widget with push notification data
I have been trying to add a control widget to my app. Now I want to show some info on control widget that is received from push notification data. In the apple documentation, they have added a push notification handler, but the pushTokensDidChange method only has the information of the controls whose push tokens are changed. There is no information on where can I access the push notification data and how to use the push notification data to update the info being shown in the control widget.
1
0
255
Sep ’24
[iOS 18] Colors from asset catalog render as pure white on tinted widgets
When a widget uses a custom color from Assets catalog. Those colors seem to be ignored and rendered as pure white when used in a widget and the Home Screen is set into the Tinted mode. This can be re-produced both in a Simulator and on a device and on the latest 18.1 beta (as of writing this post). Occasionally, I was able to catch the widget to be rendered correctly after it had been on the Home Screen for some time, but I could not identify what caused it, just re-rendering the widget by pushing a new entry into the timeline or changing the configuration, does not help the issue, colors are still rendered white. I've attached the screenshots with my widget rendered in tree different modes. Has anyone also encountered this? I'm not sure if I need to do something extra to properly support tinted mode.
1
1
978
Sep ’24
Widget loader/redact on fetch from server
I have a widget that displays data which is fetched from the server asynchronously. The widget contains a refresh button. The data is refreshed either when the app goes to the background of when the user taps the refresh button (timeline policy is .never) Since the request may take more than 2 seconds, I would like to display a redact effect until the data is returned. Lets say the timeline entry contains isRedact property. I would like to see the following happen: 1a. user taps refresh button 1b. widget is redrawn with redact state do to entry.isRedact=true 2a. data is fetched asynchronously 2b. on return widget is redrawn without redact state do to entry.isRedact=false From what I understand, the widget is re-drawn only as a result of getTimeline entries, so I don't understand how to make 1b happen, since 1b is an entry that can be created immediately but 2b entry can only happen async Of course there might be another way to redraw a widget that I don't know.
4
0
291
Sep ’24
colorScheme value always dark after setting dark mode in display and brightness even if Home Screen customization is light
If you set the display and brightness settings in iOS to be in dark mode, then the value returned in the colorScheme environment value: https://developer.apple.com/documentation/swiftui/environmentvalues/colorscheme @Environment(.colorScheme) var colorScheme is always dark, even if you toggle between light or dark in the Home Screen customization option. Tinted is reported correctly. Is there some way to get the Home Screen customization light/dark/tinted value correctly? Swapping the Home Screen customization value between light/dark does swap between the light and dark app icon so it seems like the widget color scheme should also swap in this case.
2
0
300
Sep ’24
ClockKit to WidgetKit migration bug
Hi, I'm migrating ClockKit complications to WidgetKit. Everything works well except when I run the WidgetKit version, I see complications appear twice each in the complications list for my app when adding them. If I restart the app from Xcode, it won't happen again, only for the first time. But on the actual device, only Watch restart or app reinstall fixes it which is frustrating and would not be ideal for live users. I even tried Apple's example ClockKit project -> added complications to watch face -> added WidgetKit target, CLKComplicationWidgetMigrator and func widgetConfiguration(from complicationDescriptor: CLKComplicationDescriptor) code -> run the app -> new complications appear correctly replacing old ones -> when hold to add/change complications I see it doubled (screenshot attached) and it's even selected twice If I add more complications, they will appear two times as well except one selected in two places almost like it's two same lists created. class ComplicationController: NSObject, CLKComplicationDataSource, CLKComplicationWidgetMigrator { @available(watchOSApplicationExtension 9.0, *) var widgetMigrator: CLKComplicationWidgetMigrator { self } @available(watchOSApplicationExtension 9.0, *) func widgetConfiguration(from complicationDescriptor: CLKComplicationDescriptor) async -> CLKComplicationWidgetMigrationConfiguration? { switch complicationDescriptor.identifier { case "Coffee_Tracker_Caffeine_Dose": return CLKComplicationStaticWidgetMigrationConfiguration( kind: "WidgetKitComplications", extensionBundleIdentifier: "com.example.apple-samplecode.Coffee-Tracker.watchkitapp.watchkitextension.WidgetKitComplications") default: return nil } }
4
0
441
Sep ’24
Ignore accented rendering mode?
In iOS18 the user can change their Home Screen customization to choose either light, dark, or tinted. If they choose tinted the widgets are rendered using the "accented" rendering mode and without a background. Is there some way to override so that the tinted mode is ignore completely and the widgets render as full color? I know about WidgetAccentedRenderingMode (https://developer.apple.com/documentation/widgetkit/widgetaccentedrenderingmode) but that's only for images, not the whole control and doesn't help with the background also being removed in the tinted mode.
2
0
459
2w
Control Widgets vs. Interactive Widgets
What advantages do Control Widgets offer over Interactive Widgets, besides their ability to be added to Control Center, Lock Screen, and the Action Button? As far as I understand, both types of widgets provide toggle and button actions to deep link the widget to key functions within the main app.
1
0
324
Aug ’24
Live Activity for Workout app on Apple Watch
Hi, We’ve developed a workout app with a Live Activity feature to help users launch the mirroring view on iPhone, similar to the built-in workout app for biking activities. While Live Activities are now available on watchOS 11, the integration feels a bit off for our Workout app. Is there a way to disable or exclude our Live Activity from appearing on watchOS? Currently, when a user starts a workout, the Live Activity appears at the bottom of the screen, requiring users to tap the screen before they can use our app. The built-in Workout app doesn’t have this issue. Additionally, our Live Activity appears in the Smart Stack, duplicating content with the built-in Workout Live Activity. We’re unsure if we missed any keys or settings to exclude Live Activity from watchOS.
6
1
591
Oct ’24
ControlPushHandler pushTokensDidChange never called
I'm trying to implement push notifications to update Control Center Widget as described here: https://developer.apple.com/documentation/widgetkit/updating-controls-locally-and-remotely#Use-push-notifications-to-reload-controls I've made my handler import WidgetKit import CommonTools @available(iOSApplicationExtension 18.0, *) struct ControlCenterPushHandler: ControlPushHandler { func pushTokensDidChange(controls: [ControlInfo]) { print("pushTokensDidChange called. \(controls)") controls.forEach{ print("ControlInfo \($0)") } } } And registered it for my controls var body: some ControlWidgetConfiguration { AppIntentControlConfiguration( kind: WidgetConfig.Constants.controlCenterLock, provider: Provider()) { value in ControlWidgetToggle( "Lock/Unlock", ... } .pushHandler(ControlCenterPushHandler.self) } } and then run my software on an iPhone 15 pro running iOS 18 developer beta 7. pushTokensDidChange is not called as I add and remove controls from the control panel. Or ever for that matter. If I inspect push tokens when my currentValue code runs struct Provider: AppIntentControlValueProvider { func currentValue(configuration: ControlCenterButtonConfiguration) async throws -> Value { let controls = try await ControlCenter.shared.currentControls() controls.forEach{ print("ControlInfo \($0)") } pushInfo is always nil ControlInfo ControlInfo(kind: "ControlCenterLock", pushInfo: nil, control:... What steps are needed to get a push token?
4
1
300
Aug ’24