Using Objective-C, how can I programmatically check the state of the system "Do Not Disturb" setting on OS X? I'm fine with using hacks or private APIs since I don't need to submit to the Mac App Store.
-
Did you get any solution ? if so, then please post it, I badly need it. – Mrug Feb 05 '15 at 11:14
-
I never found a solution, I gave up – Erik Feb 07 '15 at 20:47
-
This works for all usecases in swift https://github.com/sindresorhus/do-not-disturb – zengr May 06 '20 at 22:54
-
https://apple.stackexchange.com/questions/419207/turn-do-not-disturb-on-or-off-in-an-applescript-app-macos-catalina/419215#419215 – Hack-R Apr 22 '21 at 12:28
4 Answers
You can (and should) simply use UserDefaults:
let theDefaults = UserDefaults(suiteName: "com.apple.notificationcenterui")
print(theDefaults?.bool(forKey: "doNotDisturb"))
For time-controlled switching you should check if the minute of the day lies between dndStart
and dndEnd
:
let theDefaults = UserDefaults(suiteName: "com.apple.notificationcenterui")
let theDate = Date()
let theCalendar = Calendar.current
let theHour = calendar.component(.hour, from: theDate)
let theMinute = calendar.component(.minute, from: theDate)
let theMinuteOfDay = Double(theHour * 60 + theMinute)
if theMinuteOfDay >= theDefaults.double(forKey: "dndStart") &&
theMinuteOfDay <= theDefaults.double(forKey: "dndEnd") {
// ...
}

- 16,716
- 11
- 50
- 65
-
It works for me in Catalina, too. You should probably check the keys `dndStart` and `dndEnd` for time-controlled switching. – clemens Feb 09 '20 at 15:20
-
thanks for the prompt response, baffling, not working at all. Tried dndStart / dndEnd / doNotDisturb, also tried the `CFPreferencesCopyValue` variant to see if that gets me anything. Nothing. Yet, if I try this on terminal, it works. Could it be something to do with sandboxing? – strangetimes Feb 09 '20 at 15:37
-
If I print out the dictionaryRepresentation of the allocated NSUserDefaults, I can see dozens of keys / values but nothing to do with DND. – strangetimes Feb 09 '20 at 15:38
-
-
I've verified that this only works if you remove the "App Sandbox" capability from your project's "Signing & Capabilities" settings. Unfortunately removing that capability also means that your app cannot be distributed on the App Store. – alexpls Feb 12 '20 at 08:31
-
2This no longer works in Big Sur. `last-analytics-stamp` is the only entry in `com.apple.notificationcenterui` regardless of DnD settings. – Kornel Feb 13 '21 at 20:10
-
-
-
@Kornel I eventually found a script that works, see this: https://stackoverflow.com/a/69287975/217022 but otherwise the internet is full of solutions that do not :D – Paulius Liekis Sep 30 '21 at 21:22
This answer describes how to read and write the state of Do Not Disturb using the command line.
Note that the filename contains your Mac's Hardware UUID. For simplicity, it's a constant in the code below. You can figure it out using the built-in System Information app. There are also different ways to get it programmatically, like this, which I haven’t tried yet.
Using Swift, the content of the plist file can be read as NSDictionary
as follows:
import Foundation
// Get path to file
let uuid = "00000000-0000-0000-0000-000000000000"
let filepath = "~/Library/Preferences/ByHost/com.apple.notificationcenterui.\(uuid).plist".stringByExpandingTildeInPath
// Load file as `NSDictionary`
if let dict = NSDictionary(contentsOfFile: filepath) {
// Get state of Do Not Disturb
let doNotDisturbState = dict["doNotDisturb"] as? Bool
println(doNotDisturbState)
}
When I tested it, it sometimes took several seconds for the content of the plist file to be updated, hence you won't get the new state immediately after it changed.
-
1Do you know what the necessary sandbox exceptions for this method would be? – Ben Lachman Mar 11 '16 at 21:23
-
1You should never access user defaults by file directly, because macOS uses a service to manage. Thus, the file's content and the answer of `NSUserDefaults` `valueForKey` may differ. – clemens Nov 15 '16 at 07:13
In Objective-C, you can access the value like this:
NSUserDefaults* defaults = [[NSUserDefaults alloc]initWithSuiteName:@"com.apple.notificationcenterui"];
BOOL dnd = [defaults boolForKey:@"doNotDisturb"];

- 1,037
- 13
- 16
-
This no longer works in Big Sur. `last-analytics-stamp` is the only entry in `com.apple.notificationcenterui` regardless of DnD settings. – Kornel Feb 13 '21 at 20:11
Swift 4
UserDefaults(suiteName: "com.apple.notificationcenterui")?.bool(forKey: "doNotDisturb")

- 1,746
- 1
- 17
- 23
-
4
-
2There is difference between A) DND scheduled via Preferences>Notifications, B) DND turned on manually in the right-side notification area (scroll up to show the DND switch). The B) variant is probably detected correctly, but the A) variant is probably ignored. – Filip Happy Jun 28 '19 at 11:33