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) {
.
.
.