How do I make my widget update more frequently or update when an action happens within the app

Viewed 557

I have a widget that fetches data from my app. The widget works fine but doesn't update frequently enough. Ideally, id like it to update anytime an item is deleted or added in my app so if there is a way to force the widget to update, that works. Otherwise if the widget could just fetch new data more frequently then that works fine too.

The data is stored in a json file in an app group. I load and decode that data into an array and then choose a random item from that array to display.

Here's the widget Provider:

let testBook = Book(id: UUID(), name: "Name", author: "Author", genre: "Error", page: "0", total: "77")

public enum AppGroup: String {
  case Livre = "group.com.identifier"

  public var containerURL: URL {
    switch self {
    case .Livre:
      return FileManager.default.containerURL(
      forSecurityApplicationGroupIdentifier: self.rawValue)!
    }
  }
}

struct Provider: TimelineProvider {
    func placeholder(in context: Context) -> SimpleEntry {
        SimpleEntry(date: Date(), book: testBook)
    }

    func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
        let entry = SimpleEntry(date: Date(), book: testBook)
        completion(entry)
    }

    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
        var entries: [SimpleEntry] = []
            
        let currentDate = Date()
        for hourOffset in 0 ..< 5 {
            let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
            let books: [Book] = self.load("list")
            let entry = SimpleEntry(date: entryDate, book: books.randomElement() ?? testBook)
            entries.append(entry)
        }
            
        let timeline = Timeline(entries: entries, policy: .atEnd)
        completion(timeline)
        
    
    }
    
    func load<T: Decodable>(_ filename: String) -> T {
        let groupDirectory = AppGroup.Livre.containerURL
        let groupURL = groupDirectory
            .appendingPathComponent(filename)
            .appendingPathExtension("json")

        return try! JSONDecoder().decode(T.self, from: Data(contentsOf: groupURL))
    }
}

As I am new to widgetKit, im not sure if I've provided enough context, please tell me if you require anymore information or code.

1 Answers

You can always update your widget from your app with the code block below. Please be aware you need to import WidgetKit to your class for calling this function.

WidgetCenter.shared.reloadAllTimelines()
Related