I want to detect if the user has locked his screen (in macOS) using Swift.
Based on this answer I’ve created the following code:
import Cocoa
import Quartz
if let dict = Quartz.CGSessionCopyCurrentDictionary() as? [String : Any] {
let locked = dict["CGSSessionScreenIsLocked"]
print(locked as? String ?? "")
}
...which seems to work fine if I explicitly run the code.
But how is it possible to observe the value so I get notified when the value got changed?
You can observe distributed notifications. They are not documented.
let dnc = DistributedNotificationCenter.default()
lockObserver = dnc.addObserver(forName: .init("com.apple.screenIsLocked"),
object: nil, queue: .main) { _ in
NSLog("Screen Locked")
}
unlockObserver = dnc.addObserver(forName: .init("com.apple.screenIsUnlocked"),
object: nil, queue: .main) { _ in
NSLog("Screen Unlocked")
}
With Combine (available on macOS 10.15+):
import Combine
var bag = Set<AnyCancellable>()
let dnc = DistributedNotificationCenter.default()
dnc.publisher(for: Notification.Name(rawValue: "com.apple.screenIsLocked"))
.sink { _ in print("Screen Locked" }
.store(in: &bag)
dnc.publisher(for: Notification.Name(rawValue: "com.apple.screenIsUnlocked"))
.sink { _ in print("Screen Unlocked" }
.store(in: &bag)