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+

  1. I create 2 or more widgets for one counter. For example, medium and small widgets.

  2. 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.

  1. Both widgets are updated and show the new value. Everything is correct.

  2. 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.

  3. As in (2), I click the widget button to increase or decrease the value.

  4. 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?

Link to video with a problem

https://www.dropbox.com/scl/fi/9hgvz55rez79yuy748a56/CounterWidget-bug-demo.mp4?rlkey=tfct3ipx0uoqmin3tblmw34co&dl=0

I also want to ask Apple developers to make WidgetKit more user-friendly for external developers.

It was always mentioned at all WWDC sessions that WidgetKit is designed to prevent power consumption on iPhone.

  1. But why API doesn't allow updating one specific widget? I know for sure that I need to update 1, but I have to call WidgetCenter.shared.reloadAllTimelines(). So if the user has created several widgets of the same kind, I have to update them all, although I need only 1.

  2. Have you ever tried to log how many times iOS called widget extension for getTimeline() ? It may call it consecutively several times (3-4) for one widget. This wastes power on iPhone.

  3. Why are widgets that are deleted not actually deleted, but continue to exist in the background. And sometimes they can reappear on the home screen. This bug exists since iOS 14.

  4. Users periodically report that after installing an application from the appstore, widgets for it are not in the widget list. It can only be fixed by reinstalling! Sometimes users' widgets disappear when updating iOS.

  5. And this strange idea with the widget update limit. How many times I can update widget is a secret. Maybe you can make an API to find out how many times a widget can be updated, and we can at least do something with this. Now it's a lottery whether the widget will update at the specified time or not. After all, we are writing programs, not making a roulette.

  6. The main thing in my applications is the widget, and after the initial setup, users do not open the application at all, they use the widget. iOS sees that the user does not open the application and reduces the limit on widget updates. Please add an entitlement like for video applications, that this is a widget-oriented application and treats it differently.

  7. No API to wake up the main application in the background from the widget when the user pressed the button in the widget. The solution is to pull my server so that it sends a silent push to the application?

  8. API URLSessionConfiguration.background for loading data in the background for the widget, in which the documentation says that after receiving the data, pull WidgetCenter.shared.reloadAllTimelines() and this will update all widgets. But it does not always update, but when it wants. Apparently because of (5). But not only that, if the server returns a response very quickly, then the API will not go to the background at all and will not call half of the callbacks, as if it were a normal foreground application. That is, you need to guess to add a delay downloadTask.earliestBeginDate = Date (timeIntervalSinceNow: 2) so that the widget after pressing the button decides that it is still in the background and the download goes the normal way.

I made my first widget app Widget Web https://apps.apple.com/app/id1522169352 for iOS 14, and since then all these problems continue to exist.

The only useful thing that appeared during this time is Button(intent: AppIntent) in iOS 17.

I apologize if I offended anyone, I just want improvements in WidgetKit :)

In fact, the fact that the API is strange makes life difficult for everyone and therefore there are fewer competitors, but I still want to do it beautifully, as Steve taught us :)

iOS did not update all widgets of an app when the user press a button on a widget
 
 
Q