Best practice on handling application did become active

I would think that it is really common to do some updates as user enters back into the app from home screen, yet I have not seen much discussion on how this should be done in TCA context. We need to act on NSApplication.didBecomeActiveNotification and do some refresh of data.

Many of our components/reducers have implemented an action .onAppear, should we also add some action onBecomeActive, or should we support it in some other way? I think each component could be listening for a long lived effect observing for the notification, but not sure how to do that in a simplistic way. It should be easy for all developers on the team to adopt when in need of such behaviour.

An application could need support for this both on top level, and inside some random component in the app. It could be refetch of logged in user, or update a list of todo items.

This is of course a really open question, but I just wanted to hear if someone has implemented support for app did become active events in a smart way.

2 Likes

If you're using SwiftUI targeting macOS 11, you could observe the scene phase and send an action to the view store when it changes:

// in a view/app:
@Environment(\.scenePhase) private var scenePhase

// in its body:
.onChange(of: self.scenePhase) {
  viewStore.send(.didChangeScenePhase($0))
}

Probably easier, though, is to return a Notification Center publisher directly from your reducer:

case .onAppear:
  NotificationCenter.default.publisher(for: NSApplication.didBecomeActiveNotification)
  .map { _ in .didBecomeActive }
  .eraseToEffect()
  .cancellable(id: DidBecomeActiveId())

case .onDisappear:
  return .cancel(id: DidBecomeActiveId())
5 Likes