Search code examples
iosswiftuiwatchkitwatchos

How to detect when watchOS application becomes active?


I'm using watchOS 7.0 and SwiftUI. My view listens to NSExtensionHostDidBecomeActive notification:

.onReceive(NotificationCenter.default.publisher(for: .NSExtensionHostDidBecomeActive)) { _ in
    NSLog("Foreground")
    viewModel.loadData()
}

However, it is not called.


Solution

  • I solved this issue by using WKExtensionDelegate and my own notifications.

    @main
    struct ExtensionApp: App {
        @WKExtensionDelegateAdaptor(ExtensionDelegate.self) var appDelegate
    
        @SceneBuilder var body: some Scene {
            WindowGroup {
                NavigationView {
                    MainView()
                }
            }
        }
    }
    
    import WatchKit
    
    final class ExtensionDelegate: NSObject, ObservableObject, WKExtensionDelegate {
        func applicationDidFinishLaunching() {
            NSLog("App launched")
        }
    
        func applicationDidBecomeActive() {
            NSLog("App activated")
            NotificationCenter.default.post(name: .appActivated, object: nil)
        }
    
        func applicationDidEnterBackground() {
            NSLog("App deactivated")
            NotificationCenter.default.post(name: .appDeactivated, object: nil)
        }
    }
    
    import Foundation
    
    extension Notification.Name {
        static let appActivated = Notification.Name("app.activated")
        static let appDeactivated = Notification.Name("app.deactivated")
    }
    

    then I was able to listen to these events in my SwiftUI view:

    .onReceive(NotificationCenter.default.publisher(for: .appActivated)) { _ in
        viewModel.appActivated()
    }
    .onReceive(NotificationCenter.default.publisher(for: .appDeactivated)) { _ in
        viewModel.appDeactivated()
    }