In macOS program development, often need to know some state of the system changes to make certain procedures! Such as receiving system sleep, waking up, switching users, screen off, screen saver display and other system states.

  • The nsworkspace.shared. notificationCenter provides most of the system states:
    NSWorkspace .shared .notificationCenter .addObserver(self, selector: #selector(methodWillSleepNotification), name: NSWorkspace.willSleepNotification, object: nil)
    NSWorkspace .shared .notificationCenter .addObserver(self, selector: #selector(methodDidWakeNotification), name: NSWorkspace.didWakeNotification, object: nil)
    NSWorkspace .shared .notificationCenter .addObserver(self, selector: #selector(methodScreensDidSleepNotification), name: NSWorkspace.screensDidSleepNotification, object: nil)
    NSWorkspace .shared .notificationCenter .addObserver(self, selector: #selector(methodScreensDidWakeNotification), name: NSWorkspace.screensDidWakeNotification, object: nil)
    NSWorkspace .shared .notificationCenter .addObserver(self, selector: #selector(methodWillPowerOffNotification), name: NSWorkspace.willPowerOffNotification, object: nil)
    NSWorkspace .shared .notificationCenter .addObserver(self, selector: #selector(methodSessionDidResignActiveNotification), name: NSWorkspace.sessionDidResignActiveNotification, object: nil)
    NSWorkspace .shared .notificationCenter .addObserver(self, selector: #selector(methodSessionDidBecomeActiveNotification), name: NSWorkspace.sessionDidBecomeActiveNotification, object: nil)
Copy the code

Corresponding response methods:

/ / sleep / / NSWorkspace willSleepNotification @ objc func methodWillSleepNotification () { Print (" methodWillSleepNotification ")} / / wake up from sleep / / NSWorkspace didWakeNotification @ objc func methodDidWakeNotification () {print (" methodDidWakeNotification ")} sleep / / / screen/NSWorkspace screensDidSleepNotification @ objc func MethodScreensDidSleepNotification () {print (" methodScreensDidSleepNotification ")} / / screen //NSWorkspace.screensDidWakeNotification @objc func methodScreensDidWakeNotification () { Print (" methodScreensDidWakeNotification ")} / / when the user log off or shut down / / NSWorkspace willPowerOffNotification @ objc func MethodWillPowerOffNotification () {print (" methodWillPowerOffNotification ")} / / be to switch to another user //NSWorkspace.sessionDidResignActiveNotification @objc func methodSessionDidResignActiveNotification () { Print (" methodSessionDidResignActiveNotification ")} / / switch back to the current user / / NSWorkspace sessionDidBecomeActiveNotification @ objc func methodSessionDidBecomeActiveNotification () { print("methodSessionDidBecomeActiveNotification") }Copy the code

  • For some special system state (such as “screen saver”/” lock screen “* * * *), such as, requires NSDistributedNotificationCenter (notice across processes) to implement:
/ / for some system state, requires the following DistributedNotificationCenter (notice across processes) to implement:  DistributedNotificationCenter .default() .addObserver(self, selector: #selector(method_screenSaverDidStart), name: NSNotification.Name(rawValue: "com.apple.screensaver.didstart"), object: nil) DistributedNotificationCenter .default() .addObserver(self, selector: #selector(method_screenSaverWillStop), name: NSNotification.Name(rawValue: "com.apple.screensaver.willstop"), object: nil) DistributedNotificationCenter .default() .addObserver(self, selector: #selector(method_screenSaverDidStop), name: NSNotification.Name(rawValue: "com.apple.screensaver.didstop"), object: nil) DistributedNotificationCenter .default() .addObserver(self, selector: #selector(method_screenIsLocked), name: NSNotification.Name(rawValue: "com.apple.screenIsLocked"), object: nil) DistributedNotificationCenter .default() .addObserver(self, selector: #selector(method_screenIsUnlocked), name: NSNotification.Name(rawValue: "com.apple.screenIsUnlocked"), object: nil)Copy the code

Corresponding response methods:

/ / screen saver start / / "com. Apple. Screensaver. Didstart" @ objc func method_screenSaverDidStart () {print (" method_screenSaverDidStart ") } / / screen saver end / / "com. Apple. Screensaver. Willstop" @ objc func method_screenSaverWillStop () { Print (" method_screenSaverWillStop ")} / / screen saver end / / com. Apple. Screensaver. "didstop" @ objc func method_screenSaverDidStop () { Print ("method_screenSaverDidStop")} //" com.apple.screenislocked "@objc func screenIsLocked() { Print (" method_screenIsLocked ")} / / unlock / / com. Apple. "screenIsUnlocked" @ objc func method_screenIsUnlocked () { print("method_screenIsUnlocked") }Copy the code

Once you have written the code above, start the simulation scenario test

  • A. Directly select the corresponding ‘sleep’ item in the menu bar  at the top of the screen:

Print the following:

methodWillSleepNotification
methodScreensDidSleepNotification
method_screenIsLocked
method_screenIsUnlocked
methodDidWakeNotification
methodScreensDidWakeNotification
Copy the code

Wherein, click ‘sleep’ to print sleep:

methodWillSleepNotification
methodScreensDidSleepNotification
method_screenIsLocked
Copy the code

Reawakened after printing:

method_screenIsUnlocked
methodDidWakeNotification
methodScreensDidWakeNotification
Copy the code
  • B. Directly select the ‘Lock screen’ item corresponding to the top menu bar  :

Print the following:

method_screenIsLocked
method_screenIsUnlocked
Copy the code

Among them, click ‘lock screen’ to print the lock screen:

method_screenIsLocked
Copy the code

Re-enter the password of the account to unlock the screen after printing:

method_screenIsUnlocked
Copy the code

‘Desktop and Screen Savers’ and’ Save ‘in’ System Preferences’

  • C. Start ‘screen saver’ : Select the corresponding idle period

To start the ‘screen saver’, select the appropriate idle time

    • C-1. The screen saver automatically pops up, but the system has not gone to sleep:
        • [A]. Set it to ‘never’ in ‘Power Saving’ of system preferences – never hibernate

      Duration currently set to ‘never’ in ‘Save Energy’

        • [2]. Set the corresponding storage duration in ‘Energy Saving’ of system preference setting – sleep can be carried out

      The duration currently set in ‘Save Energy’ is’ 1 minute ‘.

[A], in the system preferences of the ‘save’ set to ‘never’ — whether (has been locked screen) need to enter the password to unlock the screen, (has not been locked screen) do not need to enter the password to unlock the screen!

[2], in the system preference Settings of ‘energy saving’ set to ‘1 minute’ — only the screen saver appears (the system is not sleep) to activate the computer to exit the screen saver!

The above situations [1] and [2] are printed as follows:

method_screenSaverDidStart
method_screenIsLocked
method_screenSaverWillStop
method_screenSaverDidStop
method_screenIsUnlocked
Copy the code

Where the screen saver automatically pops up to print:

method_screenSaverDidStart
method_screenIsLocked
Copy the code

Printing after unlocking the screen :(regardless of whether the account password needs to be re-entered)

method_screenSaverWillStop
method_screenSaverDidStop
method_screenIsUnlocked
Copy the code
    • C-2. The screen saver automatically pops up and is placed in the system sleep (” Save energy “in system preference setting, set the corresponding duration)

The duration currently set in ‘Save Energy’ is’ 1 minute ‘.

[$-1]. No need to re-enter the password of this account:

method_screenSaverDidStart
method_screenIsLocked
methodScreensDidSleepNotification
method_screenSaverWillStop
method_screenSaverDidStop
method_screenSaverWillStop
method_screenSaverDidStop
method_screenIsUnlocked
methodScreensDidWakeNotification
Copy the code

[$-2]. Need to re-enter the password of this account:

method_screenSaverDidStart
method_screenIsLocked
methodScreensDidSleepNotification
method_screenSaverWillStop
method_screenSaverDidStop
method_screenSaverWillStop
method_screenSaverDidStop
methodScreensDidWakeNotification
method_screenIsUnlocked
Copy the code

Among them, the screen saver automatically pops up and is then placed into the system to sleep

method_screenSaverDidStart
method_screenIsLocked
methodScreensDidSleepNotification
Copy the code

Printing after unlocking the screen:

  • [$-1]. You do not need to re-enter the password of the account
method_screenSaverWillStop
method_screenSaverDidStop
method_screenSaverWillStop
method_screenSaverDidStop
method_screenIsUnlocked
methodScreensDidWakeNotification
Copy the code
  • [$-2]. You need to re-enter the password of the account
method_screenSaverWillStop
method_screenSaverDidStop
method_screenSaverWillStop
method_screenSaverDidStop
methodScreensDidWakeNotification
method_screenIsUnlocked
Copy the code

More about the order in which system states respond to methods — try out the order in which they are called and use them together, depending on your own App needs


OC code:

[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(sleepMethod:) name:NSWorkspaceWillSleepNotification object:nil]; // The state that can be captured is: / / NSWorkspaceWillSleepNotification sleep / / / / NSWorkspaceDidWakeNotification / / wake up from sleep / / NSWorkspaceWillPowerOffNotification / / when the user log off or shut down / / NSWorkspaceSessionDidResignActiveNotification / / be to switch to another user / / NSWorkspaceSessionDidBecomeActiveNotification / / be switch back to the current user / / NSWorkspaceScreensDidSleepNotification sleep / / / / screen NSWorkspaceScreensDidWakeNotification / / screenCopy the code

Need to implement its response method (sleepMethod:)~

For some system state (such as “screen saver”/” lock screen “, etc.), you need to NSDistributedNotificationCenter (notice across processes) to implement:

[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(screensaverStart:) name:@"com.apple.screensaver.didstart" object:nil]; // The notification name can be: . / / com. Apple. Screensaver didstart / / screen saver start / / com. Apple. Screensaver. Willstop / / screen saver end / / com. Apple. Screensaver. Didstop / / screen saver end / / com. Apple. ScreenIsLocked / / screen lock / / com. Apple. ScreenIsUnlocked / / unlock screenCopy the code

Also need to implement its response method (screensaverStart:)~


The above is about the macOS system state discussion ~ for the NSApp corresponding App state discussion, please refer to “NSApp – App State and Notification”!

(2020.06.07)

goyohol’s essay