问题
class func addGlobalMonitorForEvents(matching mask: NSEvent.EventTypeMask, handler block: @escaping (NSEvent) -> Void) -> Any?{
print("this inside addGlobalMonitorForEvents")
}
NSEvent.addGlobalMonitorForEvents(matching: .flagsChanged) {
switch $0.modifierFlags.intersection(.deviceIndependentFlagsMask) {
case [.shift]:
print("shift key is pressed")
print("key code is \($0.keyCode))")
case [.control] where $0.characters == "1":
print("control key is pressed")
print("characters is \($0.characters)")
case [.option] where $0.charactersIgnoringModifiers == "1" :
print("option key is pressed")
print("\($0.charactersIgnoringModifiers) is pressed")
case [.command] where $0.keyCode == 19:
print("Command key is pressed")
print("\($0.keyCode) is pressed")
case [.command, .shift] where $0.characters == "1":
print("command-shift keys are pressed")
print("\($0.characters) are pressed")
default:
print("no modifier keys are pressed)")
}
}
Without numeric key, everything is fine. As long as I press shift / command / option with 1. It throwed exception. I tried check numeric by keyCode characters and charactersIgnoringModifiers. All of them either give me an assertion failure Assertion failure in -[NSEvent characters]
, Assertion failure in -[NSEvent charactersIgnoringModifiers]
or not failure but instead print keyCode of modifier key itself 56 or something.
I tried chain .contains(.command)
and then switch on keyCode. Samething happened.
Did I miss something here?
The code is reference from here. Although not sure what class func
did, I didn't see the "this inside addGlobalMonitorForEvents" printed out when I press keys. Without this declaration, it simply not works. So I added it anyway.
Any suggestion or explanation would be appreciated. Thanks
Update
1st code snippet the class function declartion is not necessary. Right now able to monitor local event of command+shift +1 but not global one
override func viewDidLoad(){
super.viewDidLoad()
NSEvent.addLocalMonitorForEvents(matching: .keyDown) {
self.keyDown(with: $0)
return $0
}
}
override func keyDown(with event: NSEvent) {
switch event.modifierFlags.intersection(.deviceIndependentFlagsMask) {
case [.command] where event.characters == "1", [.command, .shift] where event.characters == "1":
print("command+1 or command+shift+1")
default:
break
}
Then I changed to NSEvent.addGlobalMonitorForEvents and check xcodehelper in privacy accessibility(that's the only one I think related, as I run the app in xcode), but unfortunately that doesn't help.
回答1:
To enable AXIsProcessTrusted()
in your app you need to go to your macOS system preferences, open Security and Privacy
, click on Accessibility
, click on the plus sign to add your app to the list off apps that can control your computer. You might need to click at the padlock and type your password to unlock your settings.
import Cocoa
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("AXIsProcessTrusted:",AXIsProcessTrusted())
NSEvent.addGlobalMonitorForEvents(matching: .keyDown) {
self.keyDown(with: $0)
}
}
override func keyDown(with event: NSEvent) {
switch event.modifierFlags.intersection(.deviceIndependentFlagsMask) {
case [.command] where event.characters == "1", [.command, .shift] where event.characters == "1":
print("command+1 or command+shift+1")
default:
break
}
}
}
来源:https://stackoverflow.com/questions/58386870/cannot-read-property-keycode-character-assertion-failure-when-detect-modifie