One possibility would be to use 'AppleScriptObjc' to control the terminal via an AppleScript from Swift.
Here a complete self-contained example:
ViewController.swift
import Cocoa
import AppleScriptObjC
class ViewController: NSViewController {
var terminalBridge: TerminalBridging?
override func viewDidLoad() {
super.viewDidLoad()
Bundle.main.loadAppleScriptObjectiveCScripts()
let terminalBridgeClass: AnyClass = NSClassFromString("TerminalBridge")!
self.terminalBridge = terminalBridgeClass.alloc() as? TerminalBridging
}
@IBAction func onExecute(_ sender: Any) {
self.terminalBridge?.executeCommand("echo hello")
}
}
TerminalBriding.swift
import Cocoa
@objc(NSObject) protocol TerminalBridging {
func executeCommand(_ cmd: String)
}
TerminalBridge.applescript
Note the suffix .applescript is important. Customize it to your preferences.
script TerminalBridge
property parent : class "NSObject"
to executeCommand:cmd
tell application "Terminal"
do script (cmd as text)
end tell
end executeCommand:
end script
Setup Project in Xcode
- in XCode select the root node in the project navigator
- then select the target and under 'Frameworks, Libraries, and Embedded Content' add 'AppleScriptObjC.framework' with defult 'Do Not Embed' setting
- under 'Signing & Capabilities' remove 'App Sandbox' and add 'Hardened Runtime' instead
- scroll down and under 'Resource Access' choose 'Apple Events'
- in project navigator select 'Info.plist'
- add 'NSAppleEventsUsageDescription' key with some useful explaination
Demo
On first run you would see:
If you press 'OK' an entry is added automatically to 'System Preferences/Security & Privacy/Privacy' on first run. Afterward the command is executed.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…