Interactive Widgets With SwiftUI | Kodeco

This content was released on Jan 22 2024. The official support period is 6-months from this date.

Discover how iOS 17 takes widgets to the next level by adding interactivity. Use SwiftUI to add interactive widgets to an app called Trask. Explore different types of interactive widgets and best practices for design and development.


This is a companion discussion topic for the original entry at https://www.kodeco.com/43771410-interactive-widgets-with-swiftui

No me funciona en iOS el start project, le he cambiado el bundle, y el group, ni aun asi funciona. He seguido los pasos.
Y consulta esta articulo esta deacuerdo a lo ultimo de WWDC23 recomendaciones?
Como es posible que aconsejes un articulo del 2020, es muy antiguo. @alessandrodn

Hi @jorge_mz ,
thanks for the feedback.
Which version of Xcode are you using? I tried on Xcode 15.3 today, and everything works fine. What issue are you experiencing?

The article follows the latest content from WWDC 23, and the linked article (I guess you refer to Getting Started With Widgets | Kodeco) describes the base concepts of Widgets, which are still actual today.
During WWDC, Apple added new content on top of the Widgets API introduced in 2020.

Best
Alessandro

Hi @alessandrodn
usando la version final del proyecto, y mi Xcode es 15.5

  • ejecutando el target Trask, no me sale error pero no veo el widget por ninguna parte
  • cuando ejecuto el target TraskWidgets me sale este error
    SendProcessControlEvent:toPid: encountered an error: Error Domain=com.apple.dt.deviceprocesscontrolservice Code=8 “Failed to show Widget ‘jg.app.trask.Trask.TraskWidgets’ error: Error Domain=FBSOpenApplicationServiceErrorDomain Code=1 “The request to open “com.apple.springboard” failed.” UserInfo={NSLocalizedFailureReason=The request was denied by service delegate (SBMainWorkspace)., BSErrorCodeDescription=RequestDenied, NSUnderlyingError=0x60c01d4a0 {Error Domain=SBAvocadoDebuggingControllerErrorDomain Code=1 “Failed to get descriptors for extensionBundleID (jg.app.trask.Trask.TraskWidgets)” UserInfo={NSLocalizedDescription=Failed to get descriptors for extensionBundleID (jg.app.trask.Trask.TraskWidgets)}}, FBSOpenApplicationRequestID=0xa253, NSLocalizedDescription=The request to open “com.apple.springboard” failed.}.” UserInfo={NSLocalizedDescription=Failed to show Widget ‘jg.app.trask.Trask.TraskWidgets’ error: Error Domain=FBSOpenApplicationServiceErrorDomain Code=1 “The request to open “com.apple.springboard” failed.” UserInfo={NSLocalizedFailureReason=The request was denied by service delegate (SBMainWorkspace)., BSErrorCodeDescription=RequestDenied, NSUnderlyingError=0x60c01d4a0 {Error Domain=SBAvocadoDebuggingControllerErrorDomain Code=1 “Failed to get descriptors for extensionBundleID (jg.app.trask.Trask.TraskWidgets)” UserInfo={NSLocalizedDescription=Failed to get descriptors for extensionBundleID (jg.app.trask.Trask.TraskWidgets)}}, FBSOpenApplicationRequestID=0xa253, NSLocalizedDescription=The request to open “com.apple.springboard” failed.}., NSUnderlyingError=0x60c01f900 {Error Domain=FBSOpenApplicationServiceErrorDomain Code=1 “The request to open “com.apple.springboard” failed.” UserInfo={NSLocalizedFailureReason=The request was denied by service delegate (SBMainWorkspace)., BSErrorCodeDescription=RequestDenied, NSUnderlyingError=0x60c01d4a0 {Error Domain=SBAvocadoDebuggingControllerErrorDomain Code=1 “Failed to get descriptors for extensionBundleID (jg.app.trask.Trask.TraskWidgets)” UserInfo={NSLocalizedDescription=Failed to get descriptors for extensionBundleID (jg.app.trask.Trask.TraskWidgets)}}, FBSOpenApplicationRequestID=0xa253, NSLocalizedDescription=The request to open “com.apple.springboard” failed.}}}
    Domain: DTXMessage
    Code: 1
    User Info: {
    DVTErrorCreationDateKey = “2024-03-20 21:45:40 +0000”;
    }
    –
    SendProcessControlEvent:toPid: encountered an error: Error Domain=com.apple.dt.deviceprocesscontrolservice Code=8 “Failed to show Widget ‘jg.app.trask.Trask.TraskWidgets’ error: Error Domain=FBSOpenApplicationServiceErrorDomain Code=1 “The request to open “com.apple.springboard” failed.” UserInfo={NSLocalizedFailureReason=The request was denied by service delegate (SBMainWorkspace)., BSErrorCodeDescription=RequestDenied, NSUnderlyingError=0x60c01d4a0 {Error Domain=SBAvocadoDebuggingControllerErrorDomain Code=1 “Failed to get descriptors for extensionBundleID (jg.app.trask.Trask.TraskWidgets)” UserInfo={NSLocalizedDescription=Failed to get descriptors for extensionBundleID (jg.app.trask.Trask.TraskWidgets)}}, FBSOpenApplicationRequestID=0xa253, NSLocalizedDescription=The request to open “com.apple.springboard” failed.}.” UserInfo={NSLocalizedDescription=Failed to show Widget ‘jg.app.trask.Trask.TraskWidgets’ error: Error Domain=FBSOpenApplicationServiceErrorDomain Code=1 “The request to open “com.apple.springboard” failed.” UserInfo={NSLocalizedFailureReason=The request was denied by service delegate (SBMainWorkspace)., BSErrorCodeDescription=RequestDenied, NSUnderlyingError=0x60c01d4a0 {Error Domain=SBAvocadoDebuggingControllerErrorDomain Code=1 “Failed to get descriptors for extensionBundleID (jg.app.trask.Trask.TraskWidgets)” UserInfo={NSLocalizedDescription=Failed to get descriptors for extensionBundleID (jg.app.trask.Trask.TraskWidgets)}}, FBSOpenApplicationRequestID=0xa253, NSLocalizedDescription=The request to open “com.apple.springboard” failed.}., NSUnderlyingError=0x60c01f900 {Error Domain=FBSOpenApplicationServiceErrorDomain Code=1 “The request to open “com.apple.springboard” failed.” UserInfo={NSLocalizedFailureReason=The request was denied by service delegate (SBMainWorkspace)., BSErrorCodeDescription=RequestDenied, NSUnderlyingError=0x60c01d4a0 {Error Domain=SBAvocadoDebuggingControllerErrorDomain Code=1 “Failed to get descriptors for extensionBundleID (jg.app.trask.Trask.TraskWidgets)” UserInfo={NSLocalizedDescription=Failed to get descriptors for extensionBundleID (jg.app.trask.Trask.TraskWidgets)}}, FBSOpenApplicationRequestID=0xa253, NSLocalizedDescription=The request to open “com.apple.springboard” failed.}}}
    Domain: DTXMessage
    Code: 1
    –

System Information

macOS Version 14.4 (Build 23E214)
Xcode 15.3 (22618) (Build 15E204a)
Timestamp: 2024-03-20T16:45:40-05:00

So, I took some time to debug this and cannot reproduce the behavior you see.
Are you running the starter or the final project?
Here is a screencast I did on my project.
I’m running Xcode 15.3 with iOS simulator on iOS 17.4.
I run the Trask target, ensure you have some Todo active, and then add a Widget.
You should see the widget and the updated count.

Simulator Screen Recording - iPhone 15 - 2024-04-01 at 08.36.16.2024-04-01 09_16_07

Let me know if that works.

Great article, thank you!

I completed it successfully on Xcode 16 and iOS 17.5. I got one error when adding the TodoListProvider – I had to specify the generic Timeline as such:
func getTimeline(in context: Context, completion: @escaping (Timeline<TodoListEntry>) -> Void)
I am not sure if this is because I am using Xcode 16. Anyway, all good once I added <TodoListEntry>.

I feel ready for my next widget!

Thanks @dchakarov
I am glad to hear that, and congrats on your first widget :rocket: