Pouvez-vous exécuter un script Applescript à partir D'une Application Swift

j'ai un AppleScript simple qui envoie un email. Comment puis-je l'appeler à partir d'une application Swift?

(je n'ai pas pu trouver la réponse sur Google.)

19
demandé sur zekel 2014-08-06 18:45:19

6 réponses

pas testé, mais il semble que l'on peut faire quelque chose comme (arbitraire chemin du script d'ajout):

import Foundation

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

task.launch()
19
répondu CRGreen 2014-11-03 23:29:08

Kamaros suggère, vous pouvez appeler NSApplescript directement sans avoir à lancer un processus séparé via NSTask (comme CRGreen suggère.)

Code 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
répondu zekel 2017-05-23 11:55:10

Pour tous ceux qui se l'avertissement ci-dessous pour Swift 4, pour la ligne tout en créant un NSAppleEventDescriptor de la réponse de zekel

Non-expression en option de type "NSAppleEventDescriptor" utilisé dans une case pour les options

vous pouvez Vous débarrasser de celui-ci avec cette édité version courte:

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!)
    }
}

Toutefois, vous avez peut-être aussi réalisé; avec cette méthode, le système enregistre ce message à la console à chaque fois que vous exécutez le script:

AppleEvents: reçu mach msg qui n'était pas de type complexe comme prévu in getMemoryReference.

apparemment c'est un bug déclaré par un développeur de personnel D'Apple, et on dit que c'est juste un inoffensive log spam et prévue pour être supprimé sur les futures mises à jour OS, comme vous pouvez le voir dans ce très long apple developer forum post et donc question ci-dessous:

AppleEvents: reçu mach msg qui n'était pas de type complexe comme prévu dans getMemoryReference

Merci Apple, pour ces bazillions de bûches de consoles jetées partout.

3
répondu loopbender 2018-09-25 17:23:17

Vous pouvez essayer NSAppleScript, à partir de la note technique D'Apple TN2084 Utilisation de Scripts AppleScript dans les applications 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
répondu Yongxu Ren 2014-08-06 18:39:58

à partir de mars 2018, je pense que la réponse la plus forte sur ce fil est encore le accepté de répondre à partir de 2011. Les implémentations qui impliquaient L'utilisation de NSAppleScript ou OSAScript ont subi les inconvénients d'avoir quelques fuites de mémoire mineures, mais très désagréables, sans vraiment fournir d'avantages supplémentaires. Toute personne qui a du mal à obtenir cette réponse pour exécuter correctement (dans Swift 4) peut vouloir essayer ceci:

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
répondu Ben 2018-03-23 16:31:00

j'ai galéré quelques heures, mais rien n'a fonctionné. Finalement J'ai réussi à lancer AppleScript à travers shell:

let proc = Process()
proc.launchPath = "/usr/bin/env"
proc.arguments = ["/usr/bin/osascript", "scriptPath"]
proc.launch()

Je ne sais pas si c'est la meilleure façon de le faire, mais au moins ça marche.

1
répondu Brad Larson 2018-06-26 17:31:28