Home > database >  How to make a button in swift trigger applescript?
How to make a button in swift trigger applescript?

Time:07-13

I am making a mac menu bar app for myself by modifying the code of this program

I want my swift program to run applescript when the menu bar menu button is pressed, after reading a bit online I found that I need to look at something like NSAppleScript or AppleScriptObjC but I couldnt find a clear easy to follow example for a complete begginer like me

Curently the program is extreamly simple and only does this

What changes need to be done to my code to retain same functions of the buttons as before, but just to add that if one gets clicked it triggers/runs the applescript? (code for both - xcode swift app and the applescript are bellow)

applescript code:

if running of application "System Preferences" then
    try
        tell application "System Preferences" to quit
    on error
        do shell script "killall 'System Preferences'"
    end try
    delay 0.1
end if

repeat while running of application "System Preferences" is true
    delay 0.1
end repeat

tell application "System Preferences" to ¬
    set the current pane to pane id ¬
        "com.apple.preferences.sharing"

tell application "System Events"
    tell front window of application process "System Preferences"
        repeat until (exists checkbox 1 of row 5 of table 1 of scroll area 1 of group 1)
            delay 0.01
        end repeat
        click checkbox 1 of row 5 of table 1 of scroll area 1 of group 1
        delay 0.1
    end tell
end tell

tell application "System Preferences" to quit

xcode app code:

class AppDelegate: NSObject, NSApplicationDelegate {

    var statusItem: NSStatusItem!

    func applicationDidFinishLaunching(_ aNotification: Notification) {

        statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
        if let button = statusItem.button {
            button.image = NSImage(systemSymbolName: "1.circle", accessibilityDescription: "1")
        }

        setupMenus()
    }

    func setupMenus() {
        // 1
        let menu = NSMenu()

        // 2
        let one = NSMenuItem(title: "One", action: #selector(didTapOne) , keyEquivalent: "1")
        menu.addItem(one)

        let two = NSMenuItem(title: "Two", action: #selector(didTapTwo) , keyEquivalent: "2")
        menu.addItem(two)

        let three = NSMenuItem(title: "Three", action: #selector(didTapThree) , keyEquivalent: "3")
        menu.addItem(three)

        menu.addItem(NSMenuItem.separator())

        menu.addItem(NSMenuItem(title: "Quit", action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q"))

        // 3
        statusItem.menu = menu
    }

    // 1
    private func changeStatusBarButton(number: Int) {
        if let button = statusItem.button {
            button.image = NSImage(systemSymbolName: "\(number).circle", accessibilityDescription: number.description)
        }
    }

    @objc func didTapOne() {
        changeStatusBarButton(number: 1)
    }

    @objc func didTapTwo() {
        changeStatusBarButton(number: 2)
    }

    @objc func didTapThree() {
        changeStatusBarButton(number: 3)
    }
}

CodePudding user response:

There are a few options, but I think the "right" way is to use NSAppleScript:

import Foundation

let ascr = "tell application id \"MACS\" to reveal some item in the first Finder window"
var error: NSDictionary?
if let scriptObject = NSAppleScript(source: ascr) {
    if let scriptResult = scriptObject
        .executeAndReturnError(&error)
        .stringValue {
            print(scriptResult)
    } else if (error != nil)  { 
        print("error: ",error!)
    }
}

If you don't want to include the AppleScript code as a string value within your Swift code, you can initialise the script object from a file URL:

var error: NSDictionary?
let scptURL = URL(fileURLWithPath:"/path/to/scpt.applescript")
if let scriptObject = NSAppleScript(contentsOf:scptURL, error:&error) {
    .
    .
    .
  • Related