V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
justdoit123
V2EX  ›  Swift

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

  •  
  •   justdoit123 · May 16, 2019 · 5169 views
    This topic created in 2548 days ago, the information mentioned may be changed or developed.

    之前写了一个注册快捷键(写死在代码里)的 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 replies    2019-05-16 11:22:48 +08:00
    ioschen
        1
    ioschen  
       May 16, 2019   ❤️ 1
    justdoit123
        2
    justdoit123  
    OP
       May 16, 2019
    @ioschen 好,谢谢。我回去看看。

    这种动态需求,是不是要用闭包?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   6171 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 61ms · UTC 02:55 · PVG 10:55 · LAX 19:55 · JFK 22:55
    ♥ Do have faith in what you're doing.