inexcii
inexcii

Reputation: 1631

UIApplication.didBecomeActiveNotification Gets Called One-time Unexpectedly When User Swipe Down the Notification Center Screen on iOS Device

like the title says, I found this unexpected behavior in iOS 11 & 12.
Does anyone know why this event gets called and, more importantly, is there any workaround to prevent system from firing this UIApplication.didBecomeActiveNotification event out?

Here are the steps to reproduce this behavior:

  1. Run the application.
  2. Access the Notification Center Screen on iPhone or iPad(by swiping downward from the very top of the device's screen).
  3. At the time when the Notification Center Screen gets to the bottom of the device's screen, a UIApplication.didBecomeActiveNotification event gets fired.

You can simply add a log in AppDelegate.swift file for testing, like:

func applicationDidBecomeActive(_ application: UIApplication) {
        print("applicationDidBecomeActive")
}

I call it unexpected because when the Notification Center Screen appears, the application literally should turn to (at least semi-)background-mode and not turn back to foreground-mode unless the Notification Center Screen disappears(e.g. by swiping up to the upper-most top of the screen).
I also observed that the event did not get fired when the Control Center Screen shows up.

In my app, I'm trying the control the status of a video player when the app goes to the background(or semi-background). The unexpected .didBecomeActiveNotification event annoys the status-controlling workflow.

I searched on the Open Radar and here and googled for a while and no such related topic appeared.

Any suggestion would be appreciated. Thank you.

Upvotes: 11

Views: 3369

Answers (3)

AllenPong
AllenPong

Reputation: 15

When launching your app or switching from another app (such as system settings), the method willEnterForeground will be called and Notification, allowing us to flag and distingiush the difference.

private var willResign = false

@objc func appDidBecomeActive(_ notify: Notification) {
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
        if self.willResign == true {
            return
        }
        // Your business...
    }
}

@objc func appWillResignActive(_ notify: Notification) {
    willResign = true
}
@objc func appWillEnterForeground(_ notify: Notification) {
    willResign = false
}

Upvotes: 0

Kevin van Mierlo
Kevin van Mierlo

Reputation: 9814

I had the same problem. I have a workaround, but you cannot prevent the extra applicationDidBecomeActive. At least not that I could find. So basically what I found out was that a few milliseconds after applicationDidBecomeActive gets called, applicationWillResignActive also gets called. So if it doesn't matter that code will be executed some milliseconds later this is what I am doing:

    private var firstDidBecomeActive = true
    private var appDidBecomeActiveWorkItem: DispatchWorkItem?

    func applicationDidBecomeActive(_ application: UIApplication) {
        //Skip first time, because that is start of the app
        if self.firstDidBecomeActive {
            self.firstDidBecomeActive = false
            return
        }

        self.appDidBecomeActiveWorkItem = DispatchWorkItem {
            //Do what you want here
        }

        //Make sure there is a small delay because when user opens notification center, it becomes active again and then after a few milliseconds resigns active
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.02, execute: self.appDidBecomeActiveWorkItem!)
    }
    
    func applicationWillResignActive(_ application: UIApplication) {
        self.appDidBecomeActiveWorkItem?.cancel()
        self.appDidBecomeActiveWorkItem = nil
    }

Upvotes: 3

keerthana manoharan
keerthana manoharan

Reputation: 91

func applicationWillResignActive(_ application: UIApplication) can be used instead of .didBecomeActiveNotification, to get notified when the application goes to background or semi-background states.

Accessing the Notification Center Screen on iPhone or iPad(by swiping down from the very top of the device's screen) will call the applicationWillResignActive and it won't be triggered if we swipe up the notification center.

Upvotes: 0

Related Questions