Skip to main content

Blink/Helpers/ScriptHelper.swift

1import Foundation
3/// ScriptHelper is a helper for invoking AppleScript.
4enum ScriptHelper {
5
6 /// Execute an AppleScript via osascript with the provided arguments.
7 /// Returns the output or throws an error.
8 @discardableResult
9 static func runAppleScript(_ script: String, arguments: [String]) async throws -> String {
10 try await Task.detached(priority: .userInitiated) {
11 let task = Process()
12 task.launchPath = "/usr/bin/osascript"
14 var args = ["-e", script]
15 args.append(contentsOf: arguments)
16 task.arguments = args
18 let stdoutPipe = Pipe()
19 let stderrPipe = Pipe()
20 task.standardOutput = stdoutPipe
21 task.standardError = stderrPipe
23 try task.run()
24 task.waitUntilExit()
26 let stdout = self.readAsString(stdoutPipe)
27 let stderr = self.readAsString(stderrPipe)
29 print("AppleScript output: status=\(task.terminationStatus), stdout=\(stdout), stderr=\(stderr)")
31 if task.terminationStatus != 0 {
32 let errorMessage = stderr.isEmpty ? "Unknown AppleScript execution error." : "AppleScript execution error: \(stderr)"
33 throw NSError(
34 domain: "ScriptHelperDomain",
35 code: Int(task.terminationStatus),
36 userInfo: [NSLocalizedDescriptionKey: errorMessage]
37 )
38 }
40 return stdout
41 }.value
42 }
44 private static func readAsString(_ p: Pipe) -> String {
45 let data = p.fileHandleForReading.readDataToEndOfFile()
46 guard let output = String(data: data, encoding: .utf8) else {
47 return ""
48 }
50 return output.trimmingCharacters(in: .whitespacesAndNewlines)
51 }