Swift: How to observe if screen is locked in macOS
Asked Answered
M

2

6

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?

Mahratta answered 24/1, 2019 at 12:31 Comment(2)
Please change the question title accordingly.Pneumograph
You’re right @Desdenova, I’ve changed it.Mahratta
S
16

You can observe distributed notifications. They are not documented.

let dnc = DistributedNotificationCenter.default()

let lockObserver = dnc.addObserver(forName: .init("com.apple.screenIsLocked"),
                               object: nil, queue: .main) { _ in
    NSLog("Screen Locked")
}

let unlockObserver = dnc.addObserver(forName: .init("com.apple.screenIsUnlocked"),
                                 object: nil, queue: .main) { _ in
    NSLog("Screen Unlocked")
}
Stockinet answered 24/1, 2019 at 23:17 Comment(0)
P
1

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)
Paronychia answered 30/5, 2020 at 5:30 Comment(2)
Not working for me, nothing is printedArella
@HannesSchneidermayer is your application sandboxed? DistributedNotificationCenter doesn't work with sandboxed applications if I recall correctly.Paronychia

© 2022 - 2024 — McMap. All rights reserved.