4

I have a ios 14 widget that refresh every 5 minutes

let timeline = Timeline(entries: entries, policy: .atEnd)

The entries depends on the configuration on my MainApp.

I use UserDefaults to share data between MainApp and Widget.

@AppStorage("FollowingCatalog", store: UserDefaults(suiteName: "group.vn.f19.com"))
var catalogItemsData: Data = Data()

I've successfully mirrored the widget content base on UserDefaults data. BUT my problem is the my widget refresh the UI only after .atEnd policy, every 5 minutes

That cause a bad UX

How can I refresh widget content immediately right after my configuration in UserDefaults was changed?

Thanks for your supports.

Neo.Mxn0
  • 953
  • 2
  • 8
  • 25

3 Answers3

5

To clarify the whole workflow, I add some note here:

You can call WidgetCenter not only from widget but from your main app.

WidgetCenter.shared.reloadAllTimelines()
WidgetCenter.shared.reloadTimelines(ofKind: "com.myApp.myWidget........")

So the flow is:

  1. User change something on MainApp, eg: I rearrange the stock items in the following list

  2. MainApp save the data to UserDefaults, eg: save the list item order

  3. MainApp trigger reload widget by:

    WidgetCenter.shared.reloadTimelines(ofKind: "mone24h_widget")
    

    You can get the kind by looking into your widget entry file:

    @main
    struct mone24h_widget: Widget {
       let kind: String = "mone24h_widget"
    
  4. Widget will reload the timeline, I will get the shared data from UserDefaults here. Done the work. Eg: Re-render my stocks list base on the arrangement passed from MainApp

Neo.Mxn0
  • 953
  • 2
  • 8
  • 25
2

In Keeping a Widget Up to Date by Apple, to inform your widgets to update its timeline and its content, you call:

WidgetCenter.shared.reloadAllTimelines()

This reloads all widgets that your app has. If you want to reload a specific widget (in the case your app has multiple different widget types), use WidgetCenter.shared.reloadTimelines(ofKind: "com.myApp.myWidget") instead.

rohanphadte
  • 978
  • 6
  • 19
  • I solved the problem yesterday, initially I try to call `WidgetCenter.shared.reloadAllTimelines()` from widget instead of my main app :D – Neo.Mxn0 Oct 28 '20 at 06:48
1

BTW, if you're using react-native, I've already created a module to support this issue:

react-native-widget-bridge

Neo.Mxn0
  • 953
  • 2
  • 8
  • 25