Last active
October 4, 2024 13:18
-
-
Save sonsongithub/3b1566375a9a0fa5da7f65af49a50fcb to your computer and use it in GitHub Desktop.
AppleScript handler
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Cocoa | |
protocol CreatableFromNSAppleEventDescriptor { | |
static func get(a:NSAppleEventDescriptor) throws -> Self | |
} | |
extension Int : CreatableFromNSAppleEventDescriptor { | |
static func get(a:NSAppleEventDescriptor) throws -> Self { | |
return Int(a.int32Value) | |
} | |
} | |
extension String : CreatableFromNSAppleEventDescriptor { | |
static func get(a:NSAppleEventDescriptor) throws -> Self { | |
guard let string = a.stringValue else { | |
throw MyError.canNotGetString | |
} | |
return string | |
} | |
} | |
enum MyError: Error { | |
case appleScriptError | |
case appleScriptExecutionError(Dictionary<String, Any>) | |
case canNotGetString | |
} | |
class AppleScriptManager { | |
func call(script: String) throws -> NSAppleEventDescriptor { | |
var error: NSDictionary? | |
guard let scriptObject = NSAppleScript(source: script) else { | |
throw MyError.appleScriptError | |
} | |
let output = scriptObject.executeAndReturnError(&error) | |
if let error { | |
var dicitonary: [String: Any] = [:] | |
for key in error.allKeys { | |
if let key = key as? String { | |
dicitonary[key] = error[key] | |
} | |
} | |
throw MyError.appleScriptExecutionError(dicitonary) | |
} | |
return output | |
} | |
func execute<A: CreatableFromNSAppleEventDescriptor>(script: String) throws -> A { | |
let output = try call(script: script) | |
return try A.get(a: output) | |
} | |
func execute<A: CreatableFromNSAppleEventDescriptor>(script: String) throws -> [A] { | |
let output = try call(script: script) | |
var array: [A] = [] | |
for i in 0..<output.numberOfItems { | |
if let obj = output.atIndex(i) { | |
array.append(try A.get(a: obj)) | |
} | |
} | |
return array | |
} | |
func getVolume() throws -> Int { | |
let script = """ | |
tell application "Music" | |
set sound_volume to sound volume | |
end tell | |
sound_volume | |
""" | |
return try execute(script: script) | |
} | |
func getAirplayDevices() throws -> [String] { | |
let script = """ | |
tell application "Music" | |
set device_list to AirPlay devices | |
set device_names to {} | |
repeat with aDevice in device_list | |
set end of device_names to name of aDevice | |
end repeat | |
end tell | |
return device_names | |
""" | |
return try execute(script: script) | |
} | |
} | |
@main | |
class AppDelegate: NSObject, NSApplicationDelegate { | |
let obj = AppleScriptManager() | |
func applicationDidFinishLaunching(_ aNotification: Notification) { | |
do { | |
try obj.getVolume() | |
let a = try obj.getAirplayDevices() | |
print(a) | |
} catch { | |
print(error) | |
} | |
} | |
func applicationWillTerminate(_ aNotification: Notification) { | |
// Insert code here to tear down your application | |
} | |
func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { | |
return true | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment