UIApplication.didBecomeActiveNotification not called iOS 14

Viewed 1867

I have a project with a SceneDelegate and I am using the following code in a SwiftUI View:

.onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
    print("Did become active...")
}

It is called in iOS 13 but when I run it on iOS 14 it doesn't run.

More details: didBecomeActiveNotification is called when I put the app into foreground after having put it into background, but when app is opened for the first time it's not. But in iOS 13 it does on the first open call it.

I updated Xcode from 12.2 to 12.3 and the problem still exists. Could someone check if they get the didBecomeActiveNotification called when app is opened using iOS 14?

Any idea how to make this work?

PS. To create a project using SceneDelegate on Xcode 12 the AppName.app file should be deleted, then create SceneDelegate.swift and AppDelegate.swift files with boilerplate code and edit the info.plist "Application Scene Manifest" key to make it use SceneDelegate.

1 Answers

I did some tests and it seems you're right. I'm not sure whether it's a bug or an intended change.

The only working solution for me was onReceive + Just + scenePhase:

import Combine
import SwiftUI

struct ContentView: View {
    @Environment(\.scenePhase) private var scenePhase

    var body: some View {
        Text("Test")
            .onReceive(Just(scenePhase)) {
                print("onReceive scenePhase \($0)")
            }
    }
}

Other tests below (Xcode 14.3, iOS 12.3):

struct ContentView: View {
    @Environment(\.scenePhase) private var scenePhase

    var body: some View {
        Text("Test")
            // not working on the first launch
            .onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
                print("onReceive didBecomeActiveNotification")
            }
            // not working on the first launch
            .onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
                print("onReceive willEnterForegroundNotification")
            }
            // not working on the first launch
            .onReceive(NotificationCenter.default.publisher(for: UIApplication.didFinishLaunchingNotification)) { _ in
                print("onReceive didFinishLaunchingNotification")
            }
            // **working** on the first launch
            .onReceive(Just(scenePhase)) {
                print("onReceive scenePhase \($0)")
            }
            // not working on the first launch
            .onChange(of: scenePhase) {
                print("onChange scenePhase \($0)")
            }
    }
}
Related