J'ai un simple AppleScript qui envoie un e-mail. Comment puis-je l'appeler depuis une application Swift?
(Je n'ai pas pu trouver la réponse via Google.)
Non testé, mais il semble que l'on puisse faire quelque chose comme (chemin de script arbitraire ajouté):
import Foundation
let task = NSTask()
task.launchPath = "/usr/bin/osascript"
task.arguments = ["~/Desktop/testscript.scpt"]
task.launch()
[MISE À JOUR C'est maintenant 2019 et il y a probablement eu un certain nombre de problèmes et de changements au cours des dernières années. Voici le code mis à jour que je viens de tester sur ma machine, qui est sur OSX Mojave 10.14.5]
ObjC.import('Foundation');
let task = $.NSTask.alloc.init;
task.launchPath = "/usr/bin/osascript";
task.arguments = ["/testing_folder/test.scpt"];
task.launch
Comme 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)")
}
}
Pour tous ceux qui reçoivent l'avertissement ci-dessous pour Swift 4 , pour la ligne lors de la création d'un NSAppleEventDescriptor à partir de réponse de zekel
Expression non facultative de type "NSAppleEventDescriptor" utilisée dans une vérification des options
Vous pouvez vous en débarrasser avec cette version courte éditée:
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!)
}
}
Cependant , vous avez peut-être aussi réalisé; avec cette méthode, le système enregistre ce message sur la console chaque fois que vous exécutez le script:
AppleEvents: reçu un msg mach qui n'était pas de type complexe comme prévu dans getMemoryReference.
Apparemment, il s'agit d'un bogue déclaré par un Apple personnel, et il est dit qu'il est "juste" un spam de journal inoffensif et est prévu pour être supprimé sur les futures mises à jour du système d'exploitation, comme vous pouvez le voir dans ce très long message du forum des développeurs Apple et SO = question ci-dessous:
AppleEvents: reçu un msg mach qui n'était pas de type complexe comme prévu dans getMemoryReference
Merci Apple, pour ces bazillions de journaux de consoles indésirables jetés.
En mars 2018, je pense que la réponse la plus forte sur ce sujet est toujours la réponse acceptée de 2011 . Les implémentations qui impliquaient l'utilisation de NSAppleScript ou OSAScript ont souffert des inconvénients ayant des fuites de mémoire mineures, mais très désagréables, sans vraiment apporter d'avantages supplémentaires. Quiconque a du mal à obtenir que cette réponse s'exécute 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()
}
}
J'ai lutté quelques heures, mais rien n'a fonctionné. Enfin, j'ai réussi à exécuter AppleScript via Shell:
let proc = Process()
proc.launchPath = "/usr/bin/env"
proc.arguments = ["/usr/bin/osascript", "scriptPath"]
proc.launch()
Dunno est la meilleure façon de le faire, mais au moins cela fonctionne.
Vous pouvez essayer NSAppleScript, à partir de la note technique TN2084 d'Apple 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];