It is in fact possible for an app to know the reason why it's quitting by checking to see if there is current AppleEvent being handled and, if so, checking to see whether it's a quit event and whether it was the Dock that sent it. (See this thread discussing how to tell if an app is being quit because the system is logging out or shutting down.)
Here is an example of a method that, when called from the application delegate's applicationShouldTerminate:
method, will return true if the app is being quit via the Dock:
- (bool)isAppQuittingViaDock {
NSAppleEventDescriptor *appleEvent = [[NSAppleEventManager sharedAppleEventManager] currentAppleEvent];
if (!appleEvent) {
// No Apple event, so the app is not being quit by the Dock.
return false;
}
if ([appleEvent eventClass] != kCoreEventClass || [appleEvent eventID] != kAEQuitApplication) {
// Not a 'quit' event
return false;
}
NSAppleEventDescriptor *reason = [appleEvent attributeDescriptorForKeyword:kAEQuitReason];
if (reason) {
// If there is a reason for this 'quit' Apple event (such as the current user is logging out)
// then it didn't occur because the user quit the app through the Dock.
return false;
}
pid_t senderPID = [[appleEvent attributeDescriptorForKeyword:keySenderPIDAttr] int32Value];
if (senderPID == 0) {
return false;
}
NSRunningApplication *sender = [NSRunningApplication runningApplicationWithProcessIdentifier:senderPID];
if (!sender) {
return false;
}
return [@"com.apple.dock" isEqualToString:[sender bundleIdentifier]];
}