Czy można wykonać skrypt Applescript z aplikacji Swift

Mam prosty AppleScript, który wysyła e-mail. Jak mogę wywołać go z poziomu aplikacji Swift?

(nie udało mi się znaleźć odpowiedzi przez Google.)

Author: zekel, 2014-08-06

6 answers

Untested, ale wygląda na to, że można zrobić coś takiego (dodana Dowolna ścieżka skryptu):

import Foundation

let task = NSTask()
task.launchPath = "/usr/bin/osascript"
task.arguments = ["~/Desktop/testscript.scpt"]

task.launch()
 19
Author: CRGreen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-03 23:29:08

Jak sugeruje Kamaros, możesz wywołać NSApplescript bezpośrednio bez konieczności uruchamiania oddzielnego procesu przez NSTask (jak sugeruje CRGreen .)

Kod Swift

let myAppleScript = "..."
var error: NSDictionary?
if let scriptObject = NSAppleScript(source: myAppleScript) {
    if let output: NSAppleEventDescriptor = scriptObject.executeAndReturnError(
                                                                       &error) {
        print(output.stringValue)
    } else if (error != nil) {
        print("error: \(error)")
    }
}
 47
Author: zekel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:10

Dla każdego, kto otrzymuje ostrzeżenie poniżej dla Swift 4 , dla linii podczas tworzenia Nsapleeventdescriptor z zekel ' s answer

Nieobowiązkowe wyrażenie typu "NSAppleEventDescriptor" używane w sprawdzaniu opcji

Możesz się go pozbyć dzięki tej edycji skróconej wersji:

let myAppleScript = "..."
var error: NSDictionary?
if let scriptObject = NSAppleScript(source: myAppleScript) {
    if let outputString = scriptObject.executeAndReturnError(&error).stringValue {
        print(outputString)
    } else if (error != nil) {
        print("error: ", error!)
    }
}

Jednak, być może również zdałeś sobie sprawę; dzięki tej metodzie system rejestruje ten Komunikat do konsoli za każdym razem, gdy uruchamiasz skrypt:

AppleEvents: otrzymał mach msg, który nie był skomplikowanym typem zgodnie z oczekiwaniami in getMemoryReference.

Najwyraźniej jest to zgłoszony błąd przez programistę Apple staff, I mówi się, że jest "tylko" nieszkodliwy spam logów i jest planowane do usunięcia w przyszłych aktualizacjach systemu operacyjnego, jak widać w tym bardzo długim post na forum programistów apple i tak pytanie poniżej:

AppleEvents: otrzymał mach msg, który nie był skomplikowanym typem, jak oczekiwano w getMemoryReference

Dzięki Apple, za te bazyliony śmieciowych dzienników konsoli rzuconych wokół.

 3
Author: loopbender,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-25 17:23:17

Możesz spróbować NSAppleScript, z notki technicznej Apple TN2084 Używanie skryptów AppleScript w aplikacjach Cocoa https://developer.apple.com/library/mac/technotes/tn2084/_index.html

NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource:
            @"\
            set app_path to path to me\n\
            tell application \"System Events\"\n\
            if \"AddLoginItem\" is not in (name of every login item) then\n\
            make login item at end with properties {hidden:false, path:app_path}\n\
            end if\n\
            end tell"];

returnDescriptor = [scriptObject executeAndReturnError: &errorDict];
 2
Author: Yongxu Ren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-06 18:39:58

Według stanu na Marzec 2018, myślę, że najsilniejszą odpowiedzią w tym wątku jest nadal zaakceptowana odpowiedź z 2011 . Implementacje, które polegały na użyciu NSAppleScript lub OSAScript cierpiały na wady posiadające kilka drobnych, ale bardzo nieprzyjemne, wycieki pamięci bez naprawdę zapewniając żadnych dodatkowych korzyści. Każdy, kto ma problemy z poprawnym wykonaniem odpowiedzi (w Swift 4), może chcieć spróbować tego:

let manager = FileManager()
// Note that this assumes your .scpt file is located somewhere in the Documents directory
let script: URL? = try? manager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
if let scriptPath = script?.appendingPathComponent("/path/to/scriptName").appendingPathExtension("scpt").path {
    let process = Process()
    if process.isRunning == false {
        let pipe = Pipe()
        process.launchPath = "/usr/bin/osascript"
        process.arguments = [scriptPath]
        process.standardError = pipe
        process.launch()
    }
}
 2
Author: Ben,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-23 16:31:00

Walczyłem kilka godzin, ale nic nie działało. W końcu udało mi się uruchomić AppleScript przez shell:

let proc = Process()
proc.launchPath = "/usr/bin/env"
proc.arguments = ["/usr/bin/osascript", "scriptPath"]
proc.launch()
Nie wiem, czy to najlepszy sposób, ale przynajmniej działa.
 1
Author: Brad Larson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-26 17:31:28