title: How should I trigger network call in SwiftUI app to refresh data on app open?
body: <p>I'm writing a SwiftUI app, and I want it periodically refresh data from a server:</p>
  
  <ul>
  <li>when the app is first opened</li>
  <li>if the app enters the foreground and the data has not been updated in the past 5 minutes</li>
  </ul>
  
  <p>Below is the code I have so far.</p>
  
  <p>What is the best way to trigger this update code the first time the app is opened in a SwiftUI app? Is adding the observer in <code>onAppear</code> a good practice for triggering the update when the app enters the foreground? (This is the only view in the app)</p>
  
  <pre><code>class InfoStore {
  
      var lastValueCheck: Date = .distantPast
  }
  
  struct ContentView : View {
  
      var infoStore: InfoStore
  
      private func updateValueFromServer() {
  
          // request updated value from the server
  
          // if the request is successful, store the new value
  
          currentValue = 500
          UserDefaults.cachedValue = 500
          // hardcoded for this example
  
          infoStore.lastValueCheck = Date()
      }
  
      private func updateValueIfOld() {
  
          let fiveMinutesAgo: Date = Date(timeIntervalSinceNow: (-5 * 60))
  
          if infoStore.lastValueCheck &lt; fiveMinutesAgo {
              updateValueFromServer()
          }
      }
  
      @State var currentValue: Int = 100
  
      var body: some View {
          Text("\(currentValue)")
          .font(.largeTitle)
          .onAppear {
                  NotificationCenter.default.addObserver(forName: UIApplication.willEnterForegroundNotification,
                                                         object: nil,
                                                         queue: .main) { (notification) in
                      self.updateValueIfOld()
                  }
          }
      }
  }
  
  extension UserDefaults {
  
      private struct Keys {
          static let cachedValue = "cachedValue"
      }
  
      static var cachedValue: Int {
          get {
              return standard.value(forKey: Keys.cachedValue) as? Int ?? 0
          }
          set {
              standard.set(newValue, forKey: Keys.cachedValue)
          }
      }
  }
  </code></pre>