How to cause manual "Announce the time:" checkbox changes to take effect

macOS uses NSUserDefaults to implement defaults. It offers an Objective-C interface and is part of the Foundation framework used by System Preferences and most applications to deal with preferences.

Caching of defaults is handled by the framework and the calling application is not expected to know about or manipulate the cache. See NSUserDefaultsDidChangeNotification and Key Value Observation (KVO) for how applications can track changes.

CFPreferencesSynchronize

NSUserDefaults itself is implemented with the C based CFPreferences set of functions, found in CoreFoundation framework.

In this layer, the documentation for the function CFPreferencesSynchronize reads:

This function is the primitive synchronize mechanism for the higher level preference function CFPreferencesAppSynchronize it writes updated preferences to permanent storage, and reads the latest preferences from permanent storage.

Only the exact domain specified is modified. Note that to modify “Any User” preferences requires root privileges (or Admin privileges prior to OS X v10.6)—see Authorization Services Programming Guide.

Do not use this function directly unless you have a specific need. All arguments must be non-NULL. Do not use arbitrary user and host names, instead pass the pre-defined constants.

macOS 11.2 is partly open source. Be sure to check if defaults is part of the open section. This may be useful in determining which domains and suites the preferences affect.


I have a solution. The secret is to manipulate the macOS SpeechSynthesisServer.app after changing the Time Announce preference setting using defaults write. There is no saved copy of the settings, and no special Objective-C process is needed. (Dale Sedivec helped via email after I read his June 2019 post about System Preferences at assert.cc).

To turn "Announce the time:" ON:

defaults write ./com.apple.speech.synthesis.general.prefs TimeAnnouncementPrefs -dict-add TimeAnnouncementsEnabled -bool YES   
open /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/SpeechSynthesis.framework/Versions/A/SpeechSynthesisServer.app

To turn "Announce the time:" OFF:

defaults write ./com.apple.speech.synthesis.general.prefs TimeAnnouncementPrefs -dict-add TimeAnnouncementsEnabled -bool NO    
killall SpeechSynthesisServer # takes effect after 30 seconds

In both cases, re-launching System Preferences causes the System Preferences GUI to show the new Time Announce checkbox setting. The launching or killing of SpeechSynthesisServer.app causes the OS to respect the new setting. I'm using Keyboard Maestro to do this.