V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
justdoit123
V2EX  ›  Swift

请问 Swift 如何动态注册快捷键?

  •  
  •   justdoit123 · 2019-05-16 09:02:06 +08:00 · 4538 次点击
    这是一个创建于 2026 天前的主题,其中的信息可能已经有所发展或是发生改变。

    之前写了一个注册快捷键(写死在代码里)的 mac 工具,用来调用 AppleScript,实在不熟悉 swift,所以后来写了一个 Electronjs 版本的。

    但是,但是,但是 mac 升级到 10.14 后,nodejs 里调用 AppleScript 变得非常慢!会有 2~3 秒的延迟,泪目。

    今天尝试了一下 swift 版本,貌似延迟小了很多,但是我不懂如何实现像 nodejs 那样加载一个配置文件,然后在代码里动态注册好所有快捷键。

    google 了很久,都是些如何注册快捷键的问题。

    swift 大神,看了我的代码之后,劳烦指引个方向。

    //
    //  AppDelegate.swift
    //  hotkey-watcher
    //
    //  Created by MistKafka on 2018/5/5.
    //  Copyright © 2018 MistKafka. All rights reserved.
    //
    
    struct Keycode {
    
        // Layout-independent Keys
        // eg.These key codes are always the same key on all layouts.
        static let returnKey                 : UInt16 = 0x24
        static let enter                     : UInt16 = 0x4C
        static let tab                       : UInt16 = 0x30
        static let space                     : UInt16 = 0x31
        static let delete                    : UInt16 = 0x33
        static let escape                    : UInt16 = 0x35
        static let command                   : UInt16 = 0x37
        static let shift                     : UInt16 = 0x38
        static let capsLock                  : UInt16 = 0x39
        static let option                    : UInt16 = 0x3A
        static let control                   : UInt16 = 0x3B
        static let rightShift                : UInt16 = 0x3C
        static let rightOption               : UInt16 = 0x3D
        static let rightControl              : UInt16 = 0x3E
        static let leftArrow                 : UInt16 = 0x7B
        static let rightArrow                : UInt16 = 0x7C
        static let downArrow                 : UInt16 = 0x7D
        static let upArrow                   : UInt16 = 0x7E
        static let volumeUp                  : UInt16 = 0x48
        static let volumeDown                : UInt16 = 0x49
        static let mute                      : UInt16 = 0x4A
        static let help                      : UInt16 = 0x72
        static let home                      : UInt16 = 0x73
        static let pageUp                    : UInt16 = 0x74
        static let forwardDelete             : UInt16 = 0x75
        static let end                       : UInt16 = 0x77
        static let pageDown                  : UInt16 = 0x79
        static let function                  : UInt16 = 0x3F
        static let f1                        : UInt16 = 0x7A
        static let f2                        : UInt16 = 0x78
        static let f4                        : UInt16 = 0x76
        static let f5                        : UInt16 = 0x60
        static let f6                        : UInt16 = 0x61
        static let f7                        : UInt16 = 0x62
        static let f3                        : UInt16 = 0x63
        static let f8                        : UInt16 = 0x64
        static let f9                        : UInt16 = 0x65
        static let f10                       : UInt16 = 0x6D
        static let f11                       : UInt16 = 0x67
        static let f12                       : UInt16 = 0x6F
        static let f13                       : UInt16 = 0x69
        static let f14                       : UInt16 = 0x6B
        static let f15                       : UInt16 = 0x71
        static let f16                       : UInt16 = 0x6A
        static let f17                       : UInt16 = 0x40
        static let f18                       : UInt16 = 0x4F
        static let f19                       : UInt16 = 0x50
        static let f20                       : UInt16 = 0x5A
    
        // US-ANSI Keyboard Positions
        // eg. These key codes are for the physical key (in any keyboard layout)
        // at the location of the named key in the US-ANSI layout.
        static let a                         : UInt16 = 0x00
        static let b                         : UInt16 = 0x0B
        static let c                         : UInt16 = 0x08
        static let d                         : UInt16 = 0x02
        static let e                         : UInt16 = 0x0E
        static let f                         : UInt16 = 0x03
        static let g                         : UInt16 = 0x05
        static let h                         : UInt16 = 0x04
        static let i                         : UInt16 = 0x22
        static let j                         : UInt16 = 0x26
        static let k                         : UInt16 = 0x28
        static let l                         : UInt16 = 0x25
        static let m                         : UInt16 = 0x2E
        static let n                         : UInt16 = 0x2D
        static let o                         : UInt16 = 0x1F
        static let p                         : UInt16 = 0x23
        static let q                         : UInt16 = 0x0C
        static let r                         : UInt16 = 0x0F
        static let s                         : UInt16 = 0x01
        static let t                         : UInt16 = 0x11
        static let u                         : UInt16 = 0x20
        static let v                         : UInt16 = 0x09
        static let w                         : UInt16 = 0x0D
        static let x                         : UInt16 = 0x07
        static let y                         : UInt16 = 0x10
        static let z                         : UInt16 = 0x06
    
        static let zero                      : UInt16 = 0x1D
        static let one                       : UInt16 = 0x12
        static let two                       : UInt16 = 0x13
        static let three                     : UInt16 = 0x14
        static let four                      : UInt16 = 0x15
        static let five                      : UInt16 = 0x17
        static let six                       : UInt16 = 0x16
        static let seven                     : UInt16 = 0x1A
        static let eight                     : UInt16 = 0x1C
        static let nine                      : UInt16 = 0x19
    
        static let equals                    : UInt16 = 0x18
        static let minus                     : UInt16 = 0x1B
        static let semicolon                 : UInt16 = 0x29
        static let apostrophe                : UInt16 = 0x27
        static let comma                     : UInt16 = 0x2B
        static let period                    : UInt16 = 0x2F
        static let forwardSlash              : UInt16 = 0x2C
        static let backslash                 : UInt16 = 0x2A
        static let grave                     : UInt16 = 0x32
        static let leftBracket               : UInt16 = 0x21
        static let rightBracket              : UInt16 = 0x1E
    
        static let keypadDecimal             : UInt16 = 0x41
        static let keypadMultiply            : UInt16 = 0x43
        static let keypadPlus                : UInt16 = 0x45
        static let keypadClear               : UInt16 = 0x47
        static let keypadDivide              : UInt16 = 0x4B
        static let keypadEnter               : UInt16 = 0x4C
        static let keypadMinus               : UInt16 = 0x4E
        static let keypadEquals              : UInt16 = 0x51
        static let keypad0                   : UInt16 = 0x52
        static let keypad1                   : UInt16 = 0x53
        static let keypad2                   : UInt16 = 0x54
        static let keypad3                   : UInt16 = 0x55
        static let keypad4                   : UInt16 = 0x56
        static let keypad5                   : UInt16 = 0x57
        static let keypad6                   : UInt16 = 0x58
        static let keypad7                   : UInt16 = 0x59
        static let keypad8                   : UInt16 = 0x5B
        static let keypad9                   : UInt16 = 0x5C
    }
    
    import Cocoa
    import Magnet
    
    @NSApplicationMain
    class AppDelegate: NSObject, NSApplicationDelegate {
        @IBOutlet weak var window: NSWindow!
        let switchToSafariScript = NSAppleScript(source: "tell application \"Safari\" to activate")
        let switchToTerminalScript = NSAppleScript(source: "tell application \"Terminal\" to activate")
        let switchToChromeScript = NSAppleScript(source: "tell application \"Google Chrome\" to activate")
        let switchToEmacsScript = NSAppleScript(source: "tell application \"Emacs\" to activate")
        let switchToEmacsGitScript = NSAppleScript(source: "tell application \"Emacs-for-Git\" to activate")
        let switchToPycharmScript = NSAppleScript(source: "tell application \"PyCharm\" to activate")
    
    
        
        func applicationDidFinishLaunching(_ aNotification: Notification) {
    
            guard let keyCombo1 = KeyCombo(keyCode: Int(Keycode.s), cocoaModifiers: [.shift, .control, .command, .option]) else { return }
            let hotKey1 = HotKey(identifier: "switch-to-safari",
                keyCombo: keyCombo1,
                target: self,
                action: #selector(AppDelegate.switchToSafari))
            hotKey1.register()
            
            guard let keyCombo2 = KeyCombo(keyCode: Int(Keycode.t), cocoaModifiers: [.shift, .control, .command, .option]) else { return }
            let hotKey2 = HotKey(identifier: "switch-to-terminal",
                                 keyCombo: keyCombo2,
                                 target: self,
                                 action: #selector(AppDelegate.switchToTerminal))
            hotKey2.register()
            
            guard let keyCombo3 = KeyCombo(keyCode: Int(Keycode.c), cocoaModifiers: [.shift, .control, .command, .option]) else { return }
            let hotKey3 = HotKey(identifier: "switch-to-chrome",
                                 keyCombo: keyCombo3,
                                 target: self,
                                 action: #selector(AppDelegate.switchToChrome))
            hotKey3.register()
            
            
            guard let keyCombo5 = KeyCombo(keyCode: Int(Keycode.e), cocoaModifiers: [.shift, .control, .command, .option]) else { return }
            let hotKey5 = HotKey(identifier: "switch-to-emacs",
                                 keyCombo: keyCombo5,
                                 target: self,
                                 action: #selector(AppDelegate.switchToEmacs))
            hotKey5.register()
            
            guard let keyCombo6 = KeyCombo(keyCode: Int(Keycode.g), cocoaModifiers: [.shift, .control, .command, .option]) else { return }
            let hotKey6 = HotKey(identifier: "switch-to-emacs-git",
                                 keyCombo: keyCombo6,
                                 target: self,
                                 action: #selector(AppDelegate.switchToEmacsGit))
            hotKey6.register()
            
            guard let keyCombo7 = KeyCombo(keyCode: Int(Keycode.p), cocoaModifiers: [.shift, .control, .command, .option]) else { return }
            let hotKey7 = HotKey(identifier: "switch-to-pycharm",
                                 keyCombo: keyCombo7,
                                 target: self,
                                 action: #selector(AppDelegate.switchToPycharm))
            hotKey7.register()
        }
    
        func applicationWillTerminate(_ aNotification: Notification) {
            // Insert code here to tear down your application
        }
        
        @objc func switchToSafari() {
            self.switchTo(script: self.switchToSafariScript!)
        }
        @objc func switchToTerminal() {
            self.switchTo(script: self.switchToTerminalScript!)
        }
        @objc func switchToChrome() {
            self.switchTo(script: self.switchToChromeScript!)
        }
        @objc func switchToEmacs() {
            self.switchTo(script: self.switchToEmacsScript!)
        }
        @objc func switchToEmacsGit() {
            self.switchTo(script: self.switchToEmacsGitScript!)
        }
        @objc func switchToPycharm() {
            self.switchTo(script: self.switchToPycharmScript!)
        }
        
        func switchTo(script: NSAppleScript) {
            var error: NSDictionary?
            if let output: NSAppleEventDescriptor = script.executeAndReturnError(&error) {
                print(output.stringValue ?? "success!")
            } else {
                print("error: \(String(describing: error))")
            }
        }
    }
    
    
    2 条回复    2019-05-16 11:22:48 +08:00
    ioschen
        1
    ioschen  
       2019-05-16 10:17:44 +08:00   ❤️ 1
    justdoit123
        2
    justdoit123  
    OP
       2019-05-16 11:22:48 +08:00
    @ioschen 好,谢谢。我回去看看。

    这种动态需求,是不是要用闭包?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2209 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 01:12 · PVG 09:12 · LAX 17:12 · JFK 20:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.