Detect a user logout on macOS

Viewed 398

I am currently tryting to detect a user logout in macOS 10.14 (Mojave). I found this, which was working in the past:

Catching Logoff (not power off) event on MAC using objective C

The code I use is:

NSAppleEventManager* m = [NSAppleEventManager sharedAppleEventManager];
NSAppleEventDescriptor* desc = [m currentAppleEvent];

switch ([[desc attributeDescriptorForKeyword:kAEQuitReason] int32Value])
{
    case kAELogOut:
    case kAEReallyLogOut:
        // log out
        break;
    case kAEShowRestartDialog:
    case kAERestart:
        // system restart
        break;
    case kAEShowShutdownDialog:
    case kAEShutDown:
        // system shutdown
        break;
    default:
        // ordinary quit
        break;
}

But the value I get is always zero (0).

Did something change in Mojave or is there another mechanism? This code is called in the applicationShouldTerminate function in my AppDelegate.

1 Answers

It's still available and it works (just tested on macOS Big Sur), but the value is in the enumCodeValue property.

func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {
    let reason = NSAppleEventManager.shared()
        .currentAppleEvent?
        .attributeDescriptor(forKeyword: kAEQuitReason)
    
    switch reason?.enumCodeValue {
    case kAELogOut, kAEReallyLogOut:
        print("Logout")
        return .terminateNow
        
    case kAERestart, kAEShowRestartDialog:
        print("Restart")
        return .terminateNow
        
    case kAEShutDown, kAEShowShutdownDialog:
        print("Shutdown")
        return .terminateNow
        
    case 0:
        // `enumCodeValue` docs:
        //
        //    The contents of the descriptor, as an enumeration type,
        //    or 0 if an error occurs.
        print("We don't know")
        return .terminateNow
        
    default:
        print("Cmd-Q, Quit menu item, ...")
        return .terminateNow
    }
}
Related