AppleScript ist im alltäglichen Einsatz ein überaus nützliches Werkzeug. Wenn die Grundlagen einigermaßen sitzen, lassen sich eine ganze Reihe von Routine-Aufgaben im Finder und fast allen iLife-Programmen recht schnell erledigen. Aber AppleScript bietet über die Steuerung von Programmen eine ganze Palette an weiteren Funktionen und Möglichkeiten. Diese Fähigkeiten sind Thema dieses <openbook>. Es ist ein »work in progress« und wird in Zukunft um neue Kapitel und Abschnitte ergänzt.
Neben den Grundlagen bietet AppleScript noch weitere Finessen und Funktionalitäten, mit denen sich Skripten effizient und zielgerichtet schreiben lassen. Dieses Kapitel stellt einzelne Methoden und Verfahren vor, die im Alltag unnötige Tipparbeit ersparen können und es erlauben, sich auf die zu erreichenden Ziele zu konzentrieren. Im weiteren Sinne handelt es sich hierbei um eine Mischung aus Tipps und Tricks und »Best practice«.
Hin und wieder kann es nützlich sein, den ASCII-Code eines Zeichen heraus zu finden. AppleScript bietet mit dem Befehl ASCII number die Möglichkeit, die Nummer des angegebenen Zeichens herauszufinden. Umgekehrt kann mit ASCII character das Zeichen, das der Nummer entspricht, ausgegeben werden.
Mit dem obigen Script wird eine Liste erzeugt, die alle 255 ASCII-Zeichen und die zugehörige Nummer enthält. Auch wenn ASCII zugunsten von UTF-8 immer weiter zurücktreten muss, bei einigen Arbeiten ist der direkte Zugriff auf den ASCII-Code manchmal doch angeraten.
Nehmen die eigenen Skripten an Umfang zu, dann wird die Arbeit im Skripteditor schnell unübersichtlich. Die ganzen Klammern, Einrückungen und Funktionen tragen zur Übersicht nicht mehr viel bei und die eine oder andere Funktion, die mit viel Liebe zum Detail entwickelt würde, wäre auch bei einem ganz anderen Skript hilfreich. AppleScript bietet zwei Möglichkeiten, auf die Funktionen anderer Skripten zurück zu greifen. Zunächst ist es mit dem Befehl run script möglich, ein externes Skript aufzurufen und auszuführen. Darüber hinaus kann mit der Anweisung load script ein externes Skript geladen werden und dessen Funktionen können dann in der gleichen Weise angesprochen werden, als wären sie Teil des aufrufenden Skriptes.
Die Anweisung run script dient dazu, ein Skript aufzurufen und auszuführen, das bereits in Form einer Datei vorliegt. Dieses wird dann ausgeführt und dessen Ergebnisse stehen dem aufrufenden Skript zur Verfügung. Von besonderer Bedeutung ist hier der Handler on run. Die in dieser Funktion enthaltenen Anweisung werden ausgeführt, wenn das Skript aufgerufen wird. Im nachfolgenden Beispiel wird eine einfache Funktion definiert, die eine Variable Nachricht entgegen nimmt und eine Warnung ausgibt.
Das externe Skript besteht lediglich aus einer mit on run eingeleiteten Funktion, die eine Nachricht ausgibt.
Anstelle der simplen Ausgabe einer Nachricht könnten in diesem Skript natürlich komplizierte Anweisungen, beispielsweise die automatische Einbindung eines Netzwerk-Volumes mit anschließendem Kopiervorgang wichtiger Dateien, stehen. Dieses Skript wird nun im persönlichen Ordner des Benutzers kai auf der Partition MrsBrain mit dem Dateinamen Warnung.scpt gespeichert. Aufrufen und ausführen lässt es sich nun mit folgender Zeile:
Der Befehl run script benötigt als erstes die Angabe einer externen Datei, die das auszuführende Skript enthält. Diese Angabe muss in Form eines Dateiobjektes (Alias in der Terminologie von AppleScript) erfolgen. Daher wurde mit Hilfe der Klammern () die Angabe gleich mit Hilfe as alias in ein Dateiobjekt umgewandelt. In dem einzubindenden Skript Warnung.scpt wurde in der Funktion on run eine Variable definiert, deren Wert als Parameter übergeben werden muss. Andernfalls würde eine Fehlermeldung erfolgen, denn in Warnung.scpt wurde die Variable Nachricht nicht definiert. Die Übergabe von Parametern an ein externes Skript erfolgt durch den Zusatz with parameters und den Parametern in Form eine Liste, die mit { } umschlossen wird. In diesem Aufruf wird die Zeichenkette der Wert Obacht als Parameter übergeben. Die Variable Nachricht in dem aufgerufenen Skript Warnung.scpt hat demnach den Wert Obacht und dementsprechend wird die Dialogbox mit dem Text »Obacht« angezeigt. Es ist auch möglich, ein Skript einzubinden, dass keinerlei externer Parameter bedarf. In diesem Fall kann die Angabe with parameters komplett entfallen. Wenn mehrere Parameter von der Funktion on run benötigt werden, etwa um zwei Nachrichten auszugeben oder mehrere Ordner zu kopieren, dann muss die Liste der Parameter erweitert werden und die Angabe könnte with parameters {Wert1, Wert2, Wert3} lauten.
Der Aufruf und die automatische Ausführung eines externen Skriptes kann dann angebracht sein, wenn es für sich steht und eine klar definierte Aufgabe erfüllt. Anders verhält es sich, wenn in Funktionen für bestimmte Aufgaben wie etwa die Manipulation von Texten Lösungen entwickelt wurden, die auch anderen Skripten zugänglich gemacht werden sollen. Eine Lösung könnte natürlich darin bestehen, einfach den Quellcode der gesamten Funktion über die Zwischenablage zu kopieren und in die Skripten einzufügen. Dieses Verfahren ist aber aus zwei Gründen nicht sehr effektiv: Einerseits ist es unnötige Handarbeit und der Code der Skripten wird unnötig aufgebläht. Andererseits kann es vorkommen, dass die eine oder andere Funktion im Laufe der Zeit verbessert und verfeinert wird. Dann müsste der Quellcode aller Skripten geändert werden. Einfacher ist es, die Funktion zur Textbearbeitung in einem Skript zu speichern und dieses immer dann einzubinden, wenn Text bearbeitet werden muss. Für diese Aufgabe ist der Befehl load script vorgesehen.
Das Skript Warnung.scpt besteht nun aus einer Funktion Warnung().
Für ein einfaches Beispiel wird das Skript Warnung.scpt ein wenig modifiziert. Anstelle der Funktion on run wird nun eine Funktion Warnung mit einer Variable definiert. Auch diese Funktion gibt wieder lediglich eine Nachricht aus, aber es wäre hier auch leicht möglich, eine komplexe Routine einzufügen, die beispielsweise den Text alphabetisch sortiert und durchnummeriert.
Das Skript Warnung.scpt wird eingebunden, die darin enthaltene Funktion Warnung() aufgerufen und ihr zugleich ein Parameter übergeben.
Über load script lässt sich diese Funktion nun auch in einem anderen Skript verwenden. Der erste Schritt besteht darin, mit set Externes_Skript dem einzubindenden Skript einen Namen zu geben, unter dem es angesprochen werden kann. In diesem Fall Externes_Skript. Mit der Anweisung to load script "MrsBrain:Users:kai:Warnung.scpt" as alias wird das externe Skript geladen und seine Funktionen stehen zur Verfügung. Auch bei load script muss wie bei run script mit as alias ein Dateiobjekt angegeben werden. Die Funktionen des externen Skriptes können in Form eines tell-Blocks so angesprochen werden, als würde es sich um ein Programm oder eine Scripting Addition handeln. Hier wird lediglich die Funktion Warnung() aufgerufen und ihr der Text »Hallo« als Parameter übergeben.
Die Dialogbox wurde über die importierte Funktion Warnung() erzeugt.
Die Dialogboxen sind natürlich alles andere als eindrucksvolle Beispiele. Wie hoch die Zeit- und Arbeitsersparnis sein kann, wenn Aufgaben und Routinen in eigenen Dateien externalisiert werden, kann vielleicht bei folgendem Beispiel deutlich werden: Eine Funktion hat die Aufgabe, einen längeren Text entgegen zu nehmen und diesen anschließend in seine einzelnen Sätze zu zerlegen. Diese Sätze werden dann nach ihrer Länge sortiert und bei dieser Sortierung sollen alle Sätze, die die Zeichenfolge ABC enthalten nicht berücksichtigt und gelöscht werden. Im letzten Schritt werden alle Sätze wieder zu einem einzelnen Text zusammen gesetzt und die jetzt noch enthaltene Anzahl der Zeichen ausgegeben. Diese Textverarbeitung würde in AppleScript etliche Zeilen Code benötigen. Würde einmal eine tragfähige Funktion erarbeitet und diese in einer eigenen Datei gespeichert, dann könnten andere Skripten durch die Einbindung dieser Datei und Ansprache der enthaltenen Sortierungsfunktion sofort Texte gemäß der Vorgaben sortieren. Umgekehrt würden Verbesserungen oder Änderungen an der Funktion sofort allen Skripten zur Verfügung stehen, die auf diese Datei zurück greifen. Über kurz oder lang ließe sich so eine eigene Bibliothek an Funktionen und Routinen erstellen, die bei Bedarf zur Verfügung stehen.
AppleScript bietet über die Accounts Suite der Erweiterung System Events einige Informationen über den aktiven Benutzer. Es ist so möglich, direkt innerhalb des Skriptes den Kurz- und Langnamen des Benutzers, den absoluten Pfad zu seinem persönlichen Verzeichnis sowie den Pfad zu seinem ausgewählten Bild, das im Anmeldefenster gezeigt wird, auszulesen und zu verwenden.
Hierzu muss die Erweiterung System Events mit tell angesprochen werden. Mit einer Zeile in der Form tell application "Systems Events" to get full name of current user der Kurzname des aktiven Benutzers auslesen. Er steht dann anschließend über result zur Verfügung und könnte mit set Langname to result einer Variable zugewiesen werden. Folgende Eigenschaften können abgefragt werden:
Neben der Angabe current user, mit der die Werte des aktuell angemeldeten Benutzers ausgegeben werden, kann auch mit dem Kurznamen oder einer Zahl gezielt die Eigenschaften eines bestimmten Benutzers ausgewählt werden. Mit den Zeilen
würde der vollständige Name des Benutzers mit dem Kurznamen harald ausgegeben, unabhängig davon, ob dieser gerade angemeldet ist oder nicht. Bei der Angabe einer Zahl anstelle des Kurznamens greift AppleScript indirekt auf die Werte der NetInfo-Datenbank zurück. Innerhalb der NetInfo-Datenbank werden die Benutzerkonten eindeutig durchnummeriert und hierbei die Zahlen 501 aufwärts verwendet. Der erste auf dem System direkt nach der Installation eingerichtete Benutzer hat die UID 501. Der zweite demnach 502 usw. Innerhalb von AppleScript werden die Benutzer jedoch von 1 aufwärts gezählt. Dementsprechend ist der Benutzer, der in der NetInfo-Datenbank mit der Nummer 501 mit 1 anzusprechen. Das Skript
zählt von 1 bis 100 und gibt den Pfad des persönlichen Verzeichnisses aller eingerichteten Benutzer des Systems nacheinander aus. Wenn ein Benutzer mit der entsprechenden Nummer nicht existiert und eine Fehlermeldung ausgegeben würde, dann wird diese mit der Anweisung on error abgefangen und die Schleife mit exit repeat verlassen.
Es gibt viele Programme, die nicht über AppleScript angesprochen werden können. Ebenso sind viele Aufgaben und Handlungen denkbar, bei denen die mitgelieferten Klassen und Befehle der Programme nicht ausreichend sind und eine passende Scripting Addition nicht verfügbar ist. AppleScript bringt für solche Aufgaben die Möglichkeit mit, die grafische Oberfläche selbst zu steuern, Menüpunkte auszuwählen, Elemente anzuklicken und zum Teil auch Text einzugeben. Das Verfahren wird von Apple unter dem Begriff »Interface Scripting« zusammen gefasst.
Die Aktivierung des Zugriffs für Hilfsgeräte muss aktiviert werden.
Das Interface Scripting benötigt die Uterstützung für Hilfsgeräte. Hierzu wird in den Systemeinstellungen im Bereich Bedienungshilfen die Option Zugriff für Hilfsgeräte aktivieren ausgewählt.
Die notwendigen Funktionen innerhalb von AppleScript werden von der Process Suite der Erweiterung System Events bereit gestellt. Es wird, anders als bei der Ansprache der Funktionen eines Programms, nicht das Programm (tell application) sondern der aktive Prozess (tell process) angesprochen und gesteuert. Zusätzlich muss mit Hilfe des Programms UI Element Inspector (Download) die Bezeichnung und die Hierarchie des anzusprechenden Objektes ermittelt werden. (Eine leistungsfähige und kostenpflichtige Alternative zu dem eher rudimentären UI Element Inspector besteht in dem Programm UI Browser von PreFab.)
Wird der Inspector gestartet, dann erscheint ein schwebendes Fenster. In diesem findet sich im ersten Absatz die Hierarchie des Elements, über dem sich der Mauspfeil gerade befindet. Zu den Informationen gehören das aktive Programm (AXApplication), das entsprechende Fenster (AXWindow) und möglicherweise die Symbolleiste und der Name der Schaltfläche.
Der UI Element Inspector gibt die Bezeichnung und die Hierarchie der Elemente der grafischen Oberfläche in einem schwebenden Fenster wieder.
Die Anzeige im Inspector kann mit der Tastenkombination Apfel + F10 eingefroren werden. Der Text wird nun rot angezeigt und es erscheint untenstehendes Fenster. Wenn Sie hier die Option Highlight aktivieren, dann wird das angezeigt Element der grafischen Benutzeroberfläche rot hervorgehoben. Der Text kann nun markiert und über die Zwischenablage in den Skripteditor eingefügt werden.
Mit der Tastenkombination Apfel + F10 kann die Anzeige eingefroren werden.
In einem ersten Beispiel soll im Browser Camino ein Mausklick auf den Menüpunkt Abage • Neues Fenster ausgelöst werden. Die Hierarchie und Bezeichnung dieses Menüpunktes wird ermittelt, indem dieser mit der Maus ausgewählt wird. Im Inspector erscheint nun die Anzeige
<AXApplication: “Camino”>
<AXMenuBar>
<AXMenuBarItem: “Ablage”>
<AXMenu>
<AXMenuItem: “Neues Fenster”>
Dieser Text muss nun im Skripteditor angepasst werden. Dazu sind die Klammern, die Doppelpunkt und die Zeichen AX zu löschen. Ferner sind die »schönen« Anführungszeichen ” durch einfache Anführungszeichen " (Umschalt + 2) zu ersetzen. Als dritter und letzter Schritt müssen die Bezeichnungen wie MenuBarItem durch jeweils ein Leerzeichen vor dem Großbuchstaben getrennt (Menu Bar Item) werden. Damit ist das Grundgerüst für ein Skript, das einen Mausklick auf den Menüpunkt Neues Fenster simuliert, vorhanden.
In dem Skript selbst wird zunächst das Programm Camino mit activate in den Vordergrund geholt. Dann wird die Scripting Addition System Events, die die notwendigen Befehle für das Interface Scripting beinhaltet, angesprochen. Mit tell process "Camino" werden die in der Process Suite enthaltenen Befehle und Objekte auf den aktuellen Prozess mit der Bezeichnung Camino angewandt. Die einzelnen Elemente der grafischen Oberfläche, deren Hierarchie zuvor mit dem Inspector ermittelt wurde, werden nun der Reihe nach mit tell-Blöcken angesprochen. Bei Elementen, die im Inspector nicht mit einem Namen versehen wurden, wird mit einer Zahl für die Identifikation gesorgt. Dies ist zum Beispiel bei menu bar der Fall. Mit menu bar 1 wird hier die erste Menüzeile ausgewählt. (Es gibt in diesem Fall auch nur eine.) Am Ende der Hierarchie angelangt, wird innerhalb des tell-Blocks der auszuführende Befehl angegeben. In diesem Fall ist es click zur Simulation eines Mausklicks auf das Element Neues Fenster.
In einem zweiten Beispiel soll in den Systemeinstellungen im Bereich Sharing der Gerätename geändert werden. Ferner soll überprüft werden, ob die Firewall aktiv ist. Wenn die Firewall abgeschaltet wurde, dann wird sie von dem Skript aktiviert. Das Skript besteht aus drei wesentlichen Elementen, nachdem das Programm System Preferences, also die Systemeinstellungen, aktiviert wurden. Zuerst wird der Bereich Sharing angeklickt und, wenn dieser erschienen ist, an zwei Stellen der Name des Rechners in MrsBrain geändert. Dann wird der Reiter Firewall ausgewählt. In dieser Ansicht wird überprüft, ob die Schaltfläche zum De-/Aktivieren der Firewall dem Wert Stop entspricht. Wenn dies der Fall ist, soll die Schaltfläche angeklickt und die Firewall aktiviert werden. Hat die Schaltfläche den Wert Start, dann soll kein Klick erfolgen, denn dieser würde die Firewall abschalten.
Im ersten Schritt wird mit dem Block tell window "Systemeinstellungen" [...] end tell im Fenster Systemeinstellungen auf die Schaltfläche Sharing geklickt.1 Da die Systemeinstellungen bei einem Wechsel der Ansichten diese Überblenden, der ausgewählte Bereich also nicht unmittelbar sondern mit einer kleinen Verzögerung zur Verfügung steht, pausiert das Skript mit der Anweisung delay 1 eine Sekunde. Der Name des Fensters hat sich nun in Sharing geändert. Dies macht einen neuen tell window "Sharing"-Block notwendig, der die Elemente innerhalb des umbenannten Fensters anspricht.
In diesem Block können dann die gewünschten Änderungen vorgenommen werden. Zuerst wird mit tell text field 1
set value to "MrsBrain"
end tell
der Wert des Textfeldes mit dem Namen des Rechners in MrsBrain geändert. Dass hier mit dem Befehl set wie auch bei Variablen und Eigenschaften gearbeitet werden kann hat seinen Grund darin, dass die Werte der Elemente der grafischen Oberfläche sowohl ausgelesen als auch gesetzt werden können. Die Werte und Eigenschaften werden im Inspector unterhalb der Hierarchie im Bereich Attributes angezeigt. Es wäre zwar theoretisch auch möglich, hier wie im nächsten Beispiel mit dem Befehl keystroke zu arbeiten und eine direkte Eingabe über die Tastatur zu simulieren. In diesem Beispiel führt dies aber zu einem Konflikt mit dem Suchfeld rechts oben in den Systemeinstellungen, denn auch dieses würde über text field 1 angesprochen und in den Standardeinstellungen befindet sich der Cursor innerhalb dieses Feldes, das die Eingaben entgegen nehmen würde.
Dann wird mit tell button "Bearbeiten…" click ein Mausklick auf die Schaltfläche Bearbeiten simuliert. Dieser hat zur Folge, dass ein Ausklappmenü (sheet) erscheint. In diesem kann der Name, unter dem der Rechner im Netzwerk erscheint, geändert werden. Innerhalb der Schaltfläche ist ein Textfeld (text field 1) vorhanden. In diesem werden mit dem Befehl keystroke zwei Tastatureingaben vorgenommen. Die erste Eingabe mit keystroke "a" using command down besteht darin, die Tastenkombination Apfel + A zu simulieren. Der Befehl keystroke nimmt zunächst eine Zeichenkette entgegen. Mit Hilfe von using kann ferner eine Tastenkombination erreicht werden. Die Anweisung using command down besagt, dass die Apfel-Taste gedrückt gehalten wird. Es ist auch möglich, mit control down die ctrl-Taste, mit optioin down die Alt-Taste und mit shift down die Umschalt-Taste zu simulieren. Der nun vollständig selektierte Text wird mit keystroke "a" using command down überschrieben. Auf die Eingabe erfolgt mit tell button "OK" click ein Mausklick auf die Schaltfläche OK in dem Ausklappmenü. Der Name des Rechners im Netzwerk wurde nun in MrsBrain geändert.
Zur Überprüfung und gegebenenfalls Aktivierung der Firewall muss zunächst die passende Ansicht ausgewählt werden. Dies erfolgt mit einem Mausklick auf den Eintrag Firewall (radio button 2) im Reiter (tab group 1). Ist die Ansicht der Firewall nun verfügbar, wird der Wert der Schaltfläche, die zum de-/aktivieren dient, mit set FWStatus to title of button 3 ausgelesen. Wenn der Wert der Variable FWStatus »Start« entspricht ( if FWStatus is "Start" then), soll die Schaltfläche angeklickt werden. Andernfalls soll kein Mausklick erfolgen.
Nachdem nun alle Arbeiten erledigt wurden, wartet das Skript noch eine Sekunde und beendet dann das Programm Systemeinstellungen.
Ein simples, aber vergleichsweise nützliches Hilfsmittel kann der Befehl get UI elements darstellen. Wird er innerhalb eines tell-Blocks angewandt, so werden alle Elemente ausgegeben. Hierbei wird die Hierarchie beachtet und die Elemente, die eine Ebene tiefer liegen, werden nicht ausgegeben. Mit dem Aufruf
werden die Elemente ausgegeben, die sich im Fenster Mac-Webseite befinden. Würde der Befehl get UI Elements nicht auf das Fenster sondern direkt auf den Prozess angewandt, dann würde das Fenster als ein ansprechbares Element aufgeführt, die Elemente innerhalb des Fensters werden nicht ausgegeben.
Mit dem Befehl get UI Elements können die Elemente der grafischen Oberfläche ausgelesen werden.
Die Eigenschaften und Werte eines Elements können mit get properties ausgelesen werden.
Insbesondere in Verbindung mit Abfragen kann es manchmal notwendig sein, die Eigenschaften eines Elements abzufragen. Dies kann wie im obigen Bild mit dem Befehl get properties of erfolgen. Zu den Eigenschaften gehört unter anderem der Name, die X- und Y-Koordinate auf dem Bildschirm sowie der aktuelle Wert. Die Eigenschaften sind abhängig von der Art des abgefragten Elements. Details der zur Verfügung stehenden Eigenschaften können in der Process Suite der System Events in der Bibliothek eingesehen werden.
1Es wäre an dieser Stelle auch möglich, auf die AppleScript-Fähigkeiten der Systemeinstellungen direkt zurück zu greifen und hier das Objekt pane zu verwenden.
Bei einigen Skripten kann es notwendig sein, zufällige Werte zu verwenden. Möglicherweise soll ein temporäres Verzeichnis mit einem willkürlichen Namen erzeugt werden. Der Befehl random number erlaubt den Zugriff auf eine zufällig ausgewählte Zahl, die direkt einer Variable zugewiesen werden kann. Der einfache Aufruf von set Zufallszahl to random number weist der Variable Zufallszahl eine beliebige Zahl zwischen 0 und 1 zu. Wenn nach random number eine ganze Zahl angegeben wird, dann werden ganze Zahlen in dem Bereich zwischen 0 und der angegebenen Zahl ausgegeben. So würde man mit random number 15 zufällig ausgewählte Zahlen zwischen 0 und 15 erhalten. Mit der Angabe from ... to kann der Wertebereich genau eingegrenzt werden. Der Aufruf set Zufallszahl to random number from 1 to 10 würde eine zufällig ausgewählte Zahl zwischen 1 und 10 zuweisen.
Die Arbeit mit einem fixen Bereich kann genutzt werden, um aus einer Liste zufällig ein Element auszuwählen. In dem obigen Skript wird eine Zeichenfolge erzeugt, in der auf einen Konsonanten ein Vokal folgt. Diese Kunstworte haben zwar keine Bedeutung, lassen sich aber recht leicht aussprechen und merken. Hierzu werden zuerst zwei Listen definiert, die jeweils eine Reihe von Konsonanten un Vokalen enthalten. In der fünf mal zu durchlaufenden Schleife wird erst die Zufallszahl erzeugt und dann aus der Liste der passende Konsonant ausgewählt. Dieser wird an die Variable Ergebnis angehängt. Dann wird aus der Liste der Vokale wiederum ein Eintrag zufällig ausgewählt. Am Ende steht hier eine Zeichenfolge mit zehn Buchstaben, die zurück gegeben wird.
Neben der Steuerung von Programmen und Abläufen bringt AppleScript auch eigene Fähigkeiten mit, die den Schwerpunkt dieses Kapitels bilden. Vieler dieser Fähigkeiten von AppleScript sind eher schlecht dokumentiert, immerhin bietet die Bibliothek im Skripteditor zwar eine kurze Referenz der Befehle, aber keine Beispiele. Eigentlich ist dies recht bedauerlich, denn sowohl bei der Ansprache von Webservices als auch bei der (schnellen) Auswertung einfacher XML-Dateien kann AppleScript eine brauchbare Alternative zu einer »normalen« Programmiersprache wie Python darstellen. Vor allem integriert sich AppleScript dabei hervorragend in das Betriebssystem und mit do shell script kann bei Bedarf immer noch auf die Shell zurück gegriffen werden. Dieser Abschnitt stellt einige solcher Methoden und Techniken detaillierter vor.
Die Webservices galten vor einigen Jahren wie heutzutage das so genannte »Web 2.0« als Heilsbringer des Internet, des Webs und des E-Commerce. Mittlerweile hat sich der Wirbel ziemlich gelegt und es sind eine Reihe von kleinen und nützlichen Lösungen entstanden. Von einem Webservice wird oft gesprochen, wenn die Interaktion zwischen dem Server und dem Rechner des Anwenders im Hintergrund ohne das Zutun des Anwenders erfolgt. Genau genommen bietet bei einem Webservice der Server eine Programmierschnittstelle, die vom Anwender angesprochen und automatisch abgefragt werden kann. Bekannte Beispiele für Webservices sind die Programmierschnittstelle (API) von Google, die im Abschnitt SOAP und AppleScript behandelt wird. Auch die Arbeit mit einem Programm wie ecto setzt auf dem Webserver einen Webservice voraus. In diesem Fall wird von den meisten Content Management Systemen eine XML-RPC Schnittstelle zur Verfügung gestellt.
Die meisten Webservices basieren auf XML-Dateien. Auf dem Server werden eine Reihe von Methoden - im Falle von ecto und einem Weblog wären dies beispielsweise Eintrag erstellen, Eintrag aktualisieren, Eintrag löschen und Liste der Einträge abrufen - definiert. Das Programm des Anwenders schickt dem Server nun eine XML-Datei. Diese enthält die Anweisung, welche Aktion ausgeführt werden soll, sowie die benötigten Daten. Der Server erhält so zum Beispiel die Anweisung, dass ein neuer Eintrag publiziert werden soll, und gleichzeitig die benötigten Daten wie die Überschrift und den Haupttext. Hat der Server seine Arbeit verrichtet, dann antwortet er dem Rechner des Anwenders wiederum mit einer XML-Datei, die dann Informationen über den erfolgreichen Abschluss der Arbeit und den URL des nun verfügbaren Eintrags enthalten kann. Der Vorteil des Einsatzes von XML besteht hier darin, dass weder das Betriebssystem der eingesetzten Rechner noch die verwendeten Programmiersprachen eine Rolle spielen, so lange sie nur in der Lage sind, mit XML-Dateien umzugehen. Somit ist es möglich, einen in Java realisierten Webserver mit einem AppleScript über das Netzwerk anzusprechen.
Die beiden geläufigsten Standards für Webservices sind XML-RPC (XML Remote Process Call) und SOAP (Simple Object Access Protocoll), die beide von AppleScript unterstützt werden. Noch recht neu und unter anderem von Yahoo! favorisiert, ist das REST-Verfahren. Derzeit bietet AppleScript noch keine Unterstützung für dieses Verfahren. Der Automator ist über die Aktion Web-Dienste in der Lage, einen Webservice anzusprechen.
Von Apple gibt es auch eine englische Anleitung zur Nutzung von XML-RPC und SOAP.
XML-RPC ist einer der älteren Standards für Webservices, wurde bereits 1999 verabschiedet und vor allem durch die Verwendung durch blogger.com populär. Das Protokoll selbst ist bewusst sehr einfach gehalten und beschränkt sich auf sehr wenige Vorgaben. Die Popularisierung durch blogger.com (mittlerweile von Google aufgekauft) führte dazu, dass ein Haupteinsatzgebiet von XML-RPC in der Verwaltung von Weblogs besteht. Der ursprüngliche Funktionsumfang der Blogger API erwies sich jedoch als nicht ausreichend, so dass andere Systeme wie etwa Moveable Type Erweiterungen und Modifikationen vornahmen und sich so mehrere Verfahren etablierten.
Im Vorfeld gilt es daher die Dokumentation der auf dem Server eingesetzten Software zu konsultieren. In diesem Beispiel wird das Content Management System Drupal auf einem lokalen Webserver unter dem URL http://www.drupal.dev angesprochen. Drupal bringt drei Varianten einer XML-RPC Schnittstelle mit. Die besten Ergebnisse kann man mit der metaWeblog API erzielen. Bevor das AppleScript erstellt werden kann, muss daher in den Einstellungen von Drupal dieses Verfahren ausgewählt werden. Welche Funktionen zur Verfügung stehen, kann und sollte über die Spezifikation des Standards ermittelt werden. Ein wenig Ausdauer und Frusttoleranz sollte vorhanden sein. Da die Standards eher generisch gewachsen sind, ist ein wenig Ausprobieren manchmal nötig.
Die zu verwendende Methode wird in den Einstellungen von Drupal festgelegt.
Nach der Lektüre der Spezifikationen sollten also folgende Daten vorliegen:
In einem ersten Beispiel sollen die bereits vorhandenen Einträge über die Funktion metaWeblog.getRecentPosts abgerufen werden. In einem zweiten Skript wird ein neuer Eintrag erstellt und über die Funktion metaWeblog.newPost publiziert. Das dritte Skript stellt so etwas wie eine kleine und bescheidene Alternative zu ecto dar: Hier sollen zunächst die letzten zehn Einträge abgefragt und dem Anwender in einer Liste angezeigt werden. Dieser kann dann einen Eintrag auswählen, dessen Text bearbeiten und den geänderten Beitrag erneut publizieren.
Um die vorhandenen Einträge mit AppleScript abrufen zu können, gilt es zunächst, die notwendigen Parameter der Funktion metaWeblog.getRecentPosts zu sammeln. In der Dokumentation wird die Funktion folgendermaßen erläutert:
metaWeblog.getRecentPosts
metaWeblog.getRecentPosts (blogid, username, password, numberOfPosts) returns array of structs
Each struct represents a recent weblog post, containing the same information that a call to metaWeblog.getPost would return.
If numberOfPosts is 1, you get the most recent post. If it's 2 you also get the second most recent post, as the second array element. If numberOfPosts is greater than the number of posts in the weblog you get all the posts in the weblog.
(Quelle)
Es sind also vier Parameter notwendig: blogid, username, password, numberOfPosts. Die blogid entspricht der Nummer des Weblogs innerhalb des Content Management Systems. Bei einem Hosting-Service wie blogger.de würde dies dem Namen des gewählten Weblogs entsprechen, innerhalb von Drupal ist es lediglich die Nummer des Benutzers. In diesem Beispiel lautet der Wert 1, da es sich um das Weblog des ersten Benutzers handelt. Der username entspricht dem Benutzername im System, also Kai Surendorf. Dazu gehört natürlich auch ein Passwort, das hier lokal (!) schlicht 123 lautet. Mit numberOfPosts wird vorgegeben, wie viele der aktuellen Einträge abgerufen werden sollen. Da das Weblog noch nicht so umfangreich ist, werden lediglich die letzten fünf Einträge abgerufen.
Das eigentliche Skript zum Abrufen der vorhandenen Einträge ist recht kurz und besteht nur aus drei Zeilen:
Ein Webservice wird innerhalb von AppleScript wie ein Programm mit Hilfe von tell angesprochen. Anstelle des Namens des Programms wird hier jedoch der URL des Programms auf dem Webserver angegeben. Der URL http://www.drupal.dev/xmlrpc.php wurde der Dokumentation von Drupal entnommen. Die Anweisungen innerhalb des tell-Blocks beziehen sich dann auf die Anweisungen, die an den Server geschickt werden. Dies bedeutet in erster Linie, dass einige Funktionen wie zum Beispiel display dialog in diesem Block nicht zur Verfügung stehen, da ein Webservice keine grafische Oberfläche besitzt. Die Arbeit mit set zur Deklaration von Variablen kann jedoch erfolgen. Die Anweisung call xmlrpc schickt eine XML-RPC Anfrage an den Server, der zu Beginn des tell-Blocks angegeben wurde. Die notwendigen Parameter und Angaben werden in dem darauf folgenden Datensatz (record) angegeben. Zunächst wird mit dem Eintrag method name der Name der auszuführenden Funktion wie eben metaWeblog.getRecentPosts festgelegt. Daran schließt sich innerhalb des Datensatzes eine Liste an, die die Parameter der Anfrage beinhaltet. Hier ist die Reihenfolge gemäß den Spezifikationen der Funktion entscheidend. Zu Beginn wird als String die blogid angegeben, gefolgt vom Benutzernamen und dem Passwort. Der letzte Parameter in der Liste legt die Anzahl der abzurufenden Einträge fest und wird als Ganzzahl ohne Anführungszeichen übergeben.
Die Einträge werden in Form einer umfangreichen Liste ausgegeben.
Wenn die Anmeldung und Übergabe der Parameter an den Server funktioniert hat, dann wurden die aktuellen Einträge in der Variable Eintraege gespeichert. Es handelt sich hier um eine Liste, die in Form von Datensätzen (records) die Einträge und ihre Inhalte enthält. Mit der Anweisung set Eintrag1 to item 1 of Eintraege würde der Variable Eintrag1 der erste Eintrag in der Liste zugewiesen. Auf die Werte dieses Datensatzes wie tile für den Überschrift, postid für die Nummer innerhalb von Drupal sowie content für den eigentlichen Text könnte nun mit Anweisungen in der Form set Ueberschrift to title in Eintrag1 zugegriffen werden.
Zuständig für die Publikation eines neuen Eintrages ist die Funktion metaWeblog.newPost . In der Spezifikation findet sich für diese Funktion folgende Beschreibung:
metaWeblog.newPost (blogid, username, password, struct, publish) returns string
Wiederum müssen die Bezeichnung des Weblogs, der Benutzername und das Passwort angegeben werden. Ob es sich um einen Entwurf, der zwar gespeichert aber nicht publiziert wird, oder um einen fertigen Eintrag handelt, wird über den Parameter publish definiert. Es handelt sich hierbei um einem booleschen Wert, der entweder true für eine sofortige Publikation oder false für einen Entwurf lauten kann. Mit struct wird in dieser Spezifikation eine Variable bezeichnet, die in AppleScript einem record entspricht. Mögliche Werte können hier unter anderem title für die Überschrift und description für den Haupttext sein. Ein solches struct oder eben record könnte mit set Eintrag to {title: "Hier die Überschrift", |description|: "Hier der Haupttext"} deklariert werden. Da description eigentlich ein reserviertes Wort im Sprachraum von AppleScript ist, wird es mit dem Zeichen | maskiert. Andernfalls würde eine Fehlermeldung ausgegeben. Ein einfaches Skript, dass in zwei aufeinander folgenden Dialogboxen nach der Überschrift und dem Haupttext fragt und den Eintrag sofort publiziert, könnte folgendermaßen aussehen:
![]() |
Mit Hilfe der Leerzeichen wurde ein größeres Eingabefeld vorgegeben. |
Die vier Leerzeichen bei der zweiten display dialog-Anweisung führen dazu, dass die Eingabefläche (siehe rechts) mehr als eine Zeile umfasst und so der Haupttext besser editiert werden kann. Nachdem mit Hilfe der beiden Dialoge die Variablen Haupttext und Ueberschrift mit Text gefüllt wurden, werden diese zunächst in einem Datensatz Eintrag zusammen gefasst. Der eigentliche Aufruf des Webservice entspricht bis auf die geänderten Parameter dem ersten Beispiel.
Ein drittes Skript soll die letzten fünf Einträge abrufen und deren Überschriften dem Anwender zur Auswahl stellen. Der ausgewählte Eintrag soll dann abgerufen und dessen Überschrift und Text überarbeitet werden. Die überarbeitete Fassung wird anschließend sofort publiziert.
Im Skript sind drei XML-RPC Aufrufe notwendig: Zuerst wird die Methode metaWeblog.getRecentPosts benötigt, um die letzten fünf Einträge abzurufen und deren Überschriften auszugeben. Mit metaWeblog.getPost wird der ausgewählte Eintrag abgerufen und anschließend werden dessen Überschrift und Haupttext überarbeitet. Die überarbeitete Fassung wird dann mit metaWeblog.editPost publiziert. Da das Skript etwas länger wird, lohnt es sich mit zwei Funktionen zu arbeiten. Für die Auswahl der vorhandenen Einträge wird die Funktion Eintrag_auswaehlen() genutzt. Den Inhalt des ausgewählten Eintrags stellt die Funktion Eintrag_abrufen zur Verfügung. Damit die Anmeldedaten nicht jedes mal erneut übergeben werden müssen, werden diese zu Beginn des Skriptes als globale Eigenschaften (property) deklariert.
Die Auswahl des Eintrags erfolgt mit dem Aufruf der Funktion durch die Anweisung set Eintrag_nummer to Eintrag_auswaehlen(). In der Funktion werden zunächst die letzten fünf Überschriften abgerufen, dann deren Überschriften in einer Schleife repeat with... ausgelesen, in einer Liste Ueberschriften gespeichert und diese dann mit der Anweisung choose from list dem Anwender angezeigt. Hat dieser einen Eintrag anhand der Überschrift ausgewählt, dann gilt es noch die interne Nummer (postid) des gewählten Eintrags herauszufinden. Mit dieser Nummer, die von der Funktion zurückgegeben und in der Variable Eintrag_nummer gespeichert wird, kann dann der volle Eintrag abgerufen werden.
Die Funktion Eintrag_abrufen nimmt die Nummer (postid) des ausgewählten Eintrags entgegen und ruft ihn anschließend vom Server ab. Aus dem vollständigen Datensatz in der Variable Eintrag werden dann die Überschrift und der Haupttext ausgelesen. Die drei Werte (Nummer, Überschrift und Haupttext) werden dann in Form einer Liste zurück gegeben.
Aus der zurück gegebenen Liste Eintrag_komplett werden dann Überschrift und Haupttext ausgelesen, in zwei Dialogen zur Überarbeitung ausgegeben und die neuen Wert dann in einem Datensatz (struct bzw. record) zusammen gefügt. Schließlich erfolgt wird der so überarbeitete Eintrag an den Server geschickt.
Das Skript ließe sich sicher noch vereinfachen, kompakter fassen und einige Schritte wären durchaus zu vermeiden, wie zum Beispiel der Abruf des ausgewählten Eintrags. Dieser liegt ja bereits in der Liste Eintraege in der Funktion Eintrag_komplett vor.
Ebenso wie XML-RPC basiert auch das Simple Object Access Protocoll auf der Übermittlung von XML-Dateien zwischen dem Rechner des Anwenders und dem Server. Bei der Entwicklung des SOAP-Standards wurden etwas andere Kriterien zu Grunde gelegt als bei XML-RPC. Generell bietet die Arbeit mit SOAP deutlich mehr Funktionen als XML-RPC und das Protokoll eignet sich auch für umfangreichere Aufgabengebiete. Dies ist auch der Grund, warum sowohl Amazon als auch Google für ihre Webservices SOAP verwenden. AppleScript kann einen Webservice über SOAP ansprechen. Die Programmierschnittstelle von Google wird in diesem Artikel als Beispiel verwendet. Einerseits lassen sich hier recht schnell brauchbare und einleuchtende Ergebnisse erreichen und andererseits wurde die Schnittstelle von Google sehr umfassend und präzise dokumentiert. Die benötigten Funktionen und Parameter lassen sich in der Dokumentation recht schnell auffinden.
Google verlangt eine Registrierung, um Anfragen an die Schnittstelle senden zu dürfen. Diese kann unter http://www.google.com/apis/ kostenlos beantragt werden. Jedem registrierten Entwickler teilt Google einen Lizenzschlüssel zu, der bei jeder Abfrage übergeben werden muss. (In den Beispielen in diesem Artikel wird der Lizenzschlüssel mit 123456 angegeben.)
Nach erfolgter Registrierung wird das developer's kit benötigt, das bei Google ebenfalls kostenfrei herunter geladen werden kann. In diesem Paket findet sich die Dokumentation der Programmierschnittstelle (APIs_Reference.html) sowie eine ganze Reihe von Beispielen für verschiedene Programmiersprachen wie Java, C# und Visual Basic. Die Beispiele sind für die Arbeit mit AppleScript nicht weiter von Relevanz. Wichtig ist jedoch die in dem Paket enthaltene Datei GoogleSearch.wsdl. Die Dateiendung steht hier für Web Service Description Language. Die Datei enthält die genauen Spezifikationen, welche Methoden über die Schnittstelle von Google angesprochen werden können und welche Parameter anzugeben sind. Im weiteren Sinn handelt es sich hier um ein Pendant zur Bibliothek des Skripteditor.
Anders als C# und Java ist AppleScript nicht in der Lage, eine WSDL-Datei direkt zu interpretieren. Die in der Datei enthaltenen Anweisungen müssen zuvor mit einem speziellen Programm in eine für AppleScript verständliche Form übersetzt werden. Das benötigte Programm WSMakeStubs wird mit Xcode installiert und befindet sich im Ordner /Developer/Tools. Es kann am Terminal ausgeführt werden und verwandelt die in einer WSDL-Datei enthaltenen Vorgaben in ein AppleScript, das für eigene Skripten verwendet werden kann. Zur Konvertierung der WSDL-Datei ist am Terminal zuerst in das Verzeichnis zu wechseln, das die Datei GoogleSearch.wsdl enthält. Mit dem Aufruf /Developer/Tools/WSMakeStubs -x applescript -file GoogleSearch.wsdl wird die Datei interpretiert und in Form eines AppleScripts in der Datei WSStub.as gespeichert.
Die WSDL-Datei wurde in ein AppleScript übersetzt.
Die Datei WSStub.as enthält ein AppleScript script GoogleSearchService, dass die über die Google-Schnittstelle bereitgestellten Methoden in den drei Funktionen doSpellingSuggestion, doGoogleSearch und doGetCachedPage realisiert. Es gibt nun zwei Möglichkeiten, mit diesem Skript zu arbeiten. Zuerst ist es möglich, die Anweisungen direkt in dieser Datei auszuführen. Dazu kann das Skript mit einem tell-Block in der Form tell GoogleSearchService angesprochen werden. Es ist auch möglich, das Skript irgendwo zu speichern und mit load script (mehr) einzubinden. Für die nachfolgenden Beispiele müssen die Zeilen script GoogleSearchService und end script aus der Datei gelöscht werden. Die Datei wird im persönlichen Verzeichnis des Benutzers kai gespeichert.
Google stellt über seine Webservices drei Funktionen zur Verfügung. Mit doSpellingSuggestion wird bei einem (vermeintlichen) Tippfehler eine alternative Schreibweise vorgeschlagen. Diese Funktion ist über den Webservice nur für Englisch verfügbar. Eine Suche zu einem Begriff wird über die Funktion doGoogleSearch ausgeführt, die über eine Reihe von Parametern unter anderem zur Auswahl des Sprachgebiets gesteuert werden kann. Schließlich kann, sofern vorhanden, über doGetCachedPage eine Seite aus de Cache von Google abgerufen werden.
Vor dem eigentlichen Skript steht auch hier wieder die Lektüre der Dokumentation, die in der Datei APIs_Reference.html enthalten ist. Die Funktion doGoogleSearch nimmt insgesamt zehn Parameter entgegen. Aus diesen Parametern wird dann gemäß der WSDL-Datei eine Abfrage formuliert. Diese wird, wie auch bei der Arbeit mit XML-RPC, mit einem tell-Block an den URL des Webservice (http://api.google.com/search/beta2) geschickt. Der eigentliche Aufruf des Webservice wird hier jedoch nicht mit call xmlrpc sondern mit call soap realisiert.
Die zu übergebenden Parameter haben laut der Dokumentation von Google folgende Bedeutungen:
Wenn die mittels WSMakeStub erstellte Datei unter /Users/kai/google.scpt gespeichert und in dieser vorher die Zeilen script GoogleSearchService und end script gelöscht wurden, dann kann eine Suche bei Google mit folgendem Skript ausgeführt werden:
Mit load script wird zuerst das extern gespeicherte Skript eingebunden und mit dem Namen Google versehen. Mit der set-Anweisung wird die Suche ausgeführt und die Ergebnisse stehen dann in Form einer Liste in der Variable Ergebnisse zur Verfügung. Die Liste enthält neben den Suchergebnissen an zehnter Stelle noch einige weitere Angaben wie etwa die Dauer der Suche in Sekunden. Um auf die Suchergebnisse zugreifen zu können, kann das zehnte Element mit set Fundstellen to item 10 in Ergebnisse ausgelesen werden. Jedes Suchergebnis in der Liste ist ein Datensatz. Dieser enthält neben der Überschrift (title) die Adresse (|url|) und eine Beschreibung (snippet).
Die Treffer werden in einer Liste ausgegeben.
In dem obigen Beispiel wird wiederum eine Suche nach »Apple« im deutschen Sprachraum im Datenbestand mac ausgeführt. Die Liste wird dann auf die eigentlichen Treffer reduziert. In der repeat-Schleife wird die Liste mit den Treffern durchlaufen, die Eigenschaft |url| eines jeden Eintrags ausgelesen und anschließend mit open location im Standard-Browser geöffnet. Wenn das Skript seine Arbeit verrichtet hat, hat der Browser alle zehn Treffer automatisch geladen.
Neben der Einsparung von Mausklicks, die mit dem automatischen Aufruf aller zehn Fundstellen einher geht, lässt sich die Schnittstelle von Google natürlich für eine Vielzahl von Programmen und Aufgaben nutzen. Möglich wäre zum Beispiel bei einem Web-Projekt, bei ausgewählten Seiten eine Suche nach dem behandelten Thema auszuführen und die Fundstellen im Kontext anzubieten. Auch der »Google des Tages« des Schockwellenreiters beruht auf einer automatischen Abfrage bei Google.
Mit der Aktion Web-Dienst ausführen in der Bibliothek Automator kann auch in einem Workflow auf einen Webservice zurückgegriffen werden. Die Funktion ist noch eher rudimentär, für einen ersten Test aber ganz gut zu gebrauchen. Ein Blick in das Bundle /System/Library/Automator/Run Web Service.action verrät, dass auch hier AppleScript in Form von zwei Skripten (run web service.scpt und main.scpt) die Grundlage bietet.
Wird die Aktion in einen Workflow integriert, dann enthält sie als Beispiel eine Abfrage eines us-amerikanischen Webservice, der Staumeldungen ausgibt. Aufgrund der Struktur des Automators ist die Arbeit mit dieser Aktion in vielen Fällen nicht sehr ergiebig und zur Nachbearbeitung der Suchergebnisse wäre wahrscheinlich auf AppleScript zurück zu greifen.
Die Aktion Web-Dienste ausführen ermöglicht die Abfrage eines SOAP-Webservices im Automator.
Um die Aktion Web-Dienste ausführen nutzen zu können, müssen zusätzlich zu den Parametern noch ein paar weitere Daten aus der Dokumentation gesammelt werden. Zunächst ist als SOAP Endpunkt-URL die Adresse des Webservice anzugeben. Im Fall von Google lautet der URL http://api.google.com/search/beta2. Die SOAP-Aktion bezeichnet die Methode, die über den Webdienst aufgerufen werden soll. Dies könnte für eine Suche doGoogleSearch sein. Für die Arbeit im Automator ist diese aber denkbar schlecht geeignet, da das Ergebnis in Form einer Liste vorliegt und diese dann mit Hilfe von AppleScript ausgewertet werden müsste. Die »Rechtschreibkorrektur« von Google gibt jedoch nur einen String aus, so dass diese mit "doSpellingSuggestion" aufgerufen wird. Die Anführungszeichen müssen angegeben werden. Die SOAP-Aktion entspricht in diesem Beispiel auch dem Methodennamen, wobei hier keine Anführungszeichen anzugeben sind. Mit Methoden-Namespace wird auf ein Element des SOAP-Standards zurück gegriffen und im Beispiel von Google lautet er urn:GoogleSearch. Als Parameter wird ein Datensatz übergeben, der die von Google benötigten enthält. Hier ist als key der von Google zugeteilte Lizenzschlüssel und mit phrase das zu korrigierende Wort anzugeben. Im obigen Beispiel wurde hier Pihlosophy vorgegeben, was von Google korrekt in Philosophy korrigiert wurde.
Die Aktion eignet sich für produktive Arbeiten noch nicht so richtig und stellt eher eine Demonstration der möglicherweise in Zukunft zu erwartenden Fähigkeiten dar.
Bei Property Listen handelt es sich um nichts anderes als XML-Dateien. Diese können sowohl in reinem Text als auch in binärer Form vorliegen. Sie werden nicht nur zur Speicherung der Voreinstellung von Programmen sondern auch für andere Zwecke eingesetzt. So werden die Lesezeichen von Safari und Camino in Property Listen gespeichert. AppleScript ist in der Lage, auf die Inhalte von Property Listen zuzugreifen. Dies kann nützlich sein, wenn aus einem Skript heraus auf die Werte in einer Property List-Datei zurück gegriffen werden muss.
Werte und Eigenschaften werden in einer Property List in einer hierarchischen Struktur gespeichert.
Die Erweiterung System Events bietet über die Property List Suite Zugriff auf die Inhalte einer Property List. Um den Zugriff zu ermöglichen, kann ein Objekt mit der Anweisung property list file generiert werden. Die Anweisung benötigt, anders als sonst bei AppleScript üblich, eine Pfadanweisung in POSIX-Form und kein Alias mit Doppelpunkten. Das erzeugte Objekt kann dann wie ein Programm mit einem tell-Block angesprochen werden. Die anzusprechende Property List verfügt dann, wie auch ein Programm, über eine Reihe von Objekten und Eigenschaften, die als property list item angesprichen und mit Hilfe von set und get geändert und ausgelesen werden können.
Bei einem property list item sind zwischen den einfachen Eigenschaften, die nur einen Wert enthalten, und denen, die in Form eines Dictionary untergeordnete Einträge enthalten, zu unterscheiden. Steht das Element für sich alleine und hat einen Wert, in der obigen Abbildung wäre es die Eigenschaft state mit dem Wert No, dann kann mit der Anweisung value of auf den Wert zugegriffen werden. Bei den Elementen, die anderen übergeordnet sind, stehen zwei Möglichkeiten zur Verfügung. Auch hier kann man mit value of direkt auf den Inhalt zugreifen. Das Ergebnis bestände dann in einem verschachtelten AppleScript-Datensatz in der Form
{|Apple Remote Desktop|:{row:5, enable:0, editable:0, |port|:{"3283", "5900"}, udpport:{"3283", "5900"}}, |iPhoto Rendezvous Sharing|:{enable:0, |port|:{"8770"}, editable:1, row:10}, |Remote Login - SSH|:{enable:0, |port|:{"22"}, editable:0, row:3}, ...
Der Zugriff auf untergeordnete Objekte kann aber auch in der Form property list item XY of property list item XYZ stattfinden. Mit der Anweisung get value of property list item "Apple Remote Desktop" of property list item "firewall" würde lediglich der Wert untergeordneten Eigenschaft Apple Remote Desktop des Eintrags firewall auslesen.
Die Art der Einträge kann über die Eigenschaft kind herausgefunden werden. Die Anweisung get kind of property list item "firewall" würde als Ergebnis record enthalten. (Im Property List Editor entspricht ein record einem Dictionary mit untergeordneten Einträgen.) Die Eigenschaft state wäre vom Typ boolean und könnte den Status Yes oder No im Property List Editor oder in AppleScript den Werten true oder false entsprechen.
Nutzen lassen sich diese Fähigkeiten zum Beispiel in einem Skript, dass den Status der Firewall überprüft. Sofern die Firewall nicht aktiv ist, der Wert der Eigenschaft Status also false entspricht, ließe sich dann auch ein Skript starten, das die Firewall automatisch aktiviert. Die Anweisung display dialog steht hier außerhalb des tell Datei-Blocks, da sonst eine Fehlermeldung erfolgen würde. Eine Property List Datei kann keine
Über die XML Suite der Erweiterung System Events ist es auch mit AppleScript möglich, auf den Inhalt einer XML-Datei zuzugreifen und diese auszuwerten. Eine XML-Datei kann mit der Anweisung XML file geöffnet werden. Der Zugriff auf die Elemente innerhalb der Datei erfolgt über das Objekt XML element of. Mit value of kann der Wert des Eintrags ausgelesen werden,name of enthält die Bezeichnung.
Die XML-Datei eines RSS-Feeds enthält die Einträge in hierarchischer Form.
Die obige Abbildung zeigt den RSS-Feed von mac.delta-c, der in dem folgenden Beispiel ausgewertet werden soll. Die Abbildung ist im Programm Camino entstanden. (Die Programme aus der Mozilla-Familie besitzen die Fähigkeit, den Quellcode XML-Datei anzuzeigen.) Aus der Abbildung ergibt sich folgende Hierarchie der Tags innerhalb des XML-Dokumentes:
Die genauen Spezifikation kann bei Bedarf dem entsprechenden Standard entnommen werden.
Die Inhalte sind also einzelne Elemente des Elements channel des Elements rss mit der Bezeichnung item. Der Satz ist bewusst etwas unelegant formuliert, denn in AppleScript würde die Anweisung zum Abruf des ersten Elements set Eintrag to (XML element 1 of XML element "channel" of XML element "rss" of contents of XMLDatei whose name is "item") lauten. Der Aufbau der XML-Datei, der sich von oben nach unten ergibt, wird in den AppleScript-Anweisungen von rechts nach links realisiert.
Bei der mit diesem Befehl definierten Variable Eintrag handelt es sich um ein XML Element. Mit set Ueberschrift to value of XML element "title" of Eintrag könnte die Überschrift, mit set Haupttext to value of XML element "description" of Eintrag die Beschreibung ausgelesen werden.
In Kombination mit dem Befehl do shell script und dem Programm curl ließe sich also mit AppleScript ein kleiner Newsreader basteln:
In dem Skript wird zuerst der aktuelle Newsfeed aus dem Internet geladen und in der Datei feed.xml gespeichert. Dann folgenden Anweisungen ergehen an die Erweiterung System Events. Zuerst wird die gespeicherte Datei als XML file geöffnet. Dann wird in der repeat-Schleife zuerst das jeweilige item-Element aus der Datei gelesen, diesem die Ueberschrift und der Haupttext entnommen und beide dann in einer Dialogbox angezeigt.
Im obigen Beispiel wurde das Tag <rss version="2.0" xml:base="http://mac.delta-c.de"> lediglich als Behälter der untergeordneten Einträge behandelt. Es enthält jedoch in sich zwei Attribute. AppleScript ermöglicht mit der Anweisung XML attribute den Zugriff auf solche Attribute. So ließe sich im obigen Skript mit der Anweisung get name of XML attribute 1 of XML element "rss" of datei die verwendete Version des RSS Formates ermitteln.
AppleScript ist nicht auf den eingebauten Befehlsschatz und die Funktionen, die über Programme zur Verfügung gestellt, beschränkt, sondern lässt sich um neue Funktionen und Befehle ergänzen. Grundlage hierfür ist die Open Scripting Architecture (OSA). Diese schon unter Mac OS Classic verfügbare Schnittstelle ermöglicht es Programmierern, eigene Module für AppleScript zu entwickeln. Diese Scripting Additions werden manchmal auch mit dem Akronym OSAX bezeichnet und mit der Dateiendung .osax sowie einem Legostein als Icon versehen.
Um eine Erweiterung zu installieren, müssen die jeweiligen *.osax-Dateien zunächst entweder in das Verzeichnis /Library/ScriptingAdditions für alle eingerichteten Benutzer oder ~/Library/ScriptingAdditions für den Eigentümer des privaten Verzeichnisses kopiert werden. Um den Befehlsschatz der Erweiterung in der Bibliothek des Skripteditors einzusehen, muss die Erweiterung wie auch bei einem Programm über das Icon + und der anschließenden Auswahl ihrer Datei der Bibliothek hinzugefügt werden.

Die Erweiterung XMail wurde in das Verzeichnis ~/Library/ScriptingAdditions kopiert und der Bibliothek hinzugefügt.
Im Laufe der Zeit sind eine ganze Reihe von nützlichen und bisweilen auch witzigen Erweiterunge von AppleScript entstanden. Dieser Abschnitt des <openbook> stellt Ihnen einige ausgewählte Erweiterungen vor.
Um E-Mails mit Hilfe eines Skriptes an beliebig viele Empfänger zu verschicken, kann man sich eines Shell-Skriptes und dem Mail-Server Postfix bedienen. Hierzu muss sich der Anwender schon recht gut mit dem UNIX-Unterbau von Mac OS X auskennen. Einfacher ist es, E-Mails direkt aus AppleScript heraus zu verschicken. Die Open Scripting Architecture und die passende Erweiterung machen es möglich.
|
|
Die Erweiterung wird im Ordner Scripting Additions in der Library installiert. |
Um die Syntax und die möglichen Optionen des Befehls send mail auch in der Bibliothek des Skripteditors anzuzeigen, muss sie ggf. noch mit dem Plus-Zeichen der Bibliothek der Sammlung hinzugefügt werden. Anschließend kann man sich die Optionen, wie in untenstehender Abbildung zu sehen, auch im Skripteditor anzeigen lassen.
|
|
Der Befehl send mail verfügt über alle notwendigen Parameter und Funktionen. |
Zum Versand einer E-Mail werden einfach dem Befehl send mail die enstprechenden Optionen übergeben. Im untenstehenden Beispiel sind die Angaben fast selbsterklärend. Bei der Authentifizierung gegenüber dem SMTP-Server muss die Methode manchmal explizit angegeben werden, oft reicht aber einfach die Angabe von authentication auto.
<!-- AppleScript Formatting Start -->
<!-- AppleScript Formatting End -->
Die Erweiterung XMail beherrscht auch den Versand von Dateien. Im untenstehenden Beispiel wird zuerst mit set datei to choose file eine Datei vom Anwender ausgewählt und in der Variable datei gespeichert. Anschließend wird diese an die E-Mail mit attachments {datei} angehängt. Es ist auch möglich, mehrere Dateien zu verschicken, indem sie in den geschweiften Klammern durch Kommata getrennt attachments {datei1, datei2} angegeben werden.
<!-- AppleScript Formatting End -->
... sind mit dieser Erweiterung leicht möglich. Es ist ohne Probleme möglich, etwa aus einer FileMaker-Datenbank sowohl den Nachnamen, die Anrede und die E-Mail-Adresse des Kunden auszulesen, diese Werte in Variablen zu speichern und zusammen mit weiteren Textbausteinen in eine persönliche E-Mail zusammen zu fassen.
XMail erfüllt zielgerichtet und zuverlässig seinen Zweck. Die Verwendung des Befehls send mail bereitet keine Probleme und die Möglichkeit, E-Mails auch als cc und bcc zu verschicken, macht die Erweiterung zu einem vollwertigen Ersatz. Die mühsame Programmierung von Apples eigenem Mail-Programm wird überflüssig.
Mit XFun steht eine witzige Erweiterung der Fähigkeiten von AppleScript zur Verfügung. Mit ihrer Hilfe lassen sich die Fenster einer Anwendung mit Transparenz versehen, dem Icon im Dock ein Badge mit einer Zahl hinzufügen und der Poof-Effekt an einer beliebigen Stelle auf dem Bildschirm ausführen.
|
|
Das linke Fenster wurde mit dem Befehl opacity mit einer Transparenz versehen. |
Dass die in Mac OS X integrierte Grafik-Engine Quartz enorm leistungsfähig ist, dürfte sich mittlerweile herum gesprochen haben. Eines der bestechenden Features – im direkten Vergleich zu Windows – ist die an allen Orten teilweise auch dezent eingesetzte Transparenz. XFun enthält den Befehl opacity, der ein Fenster transparent erscheinen lässt. Mit dem Skript
opacity 0.7 target 1
end tell
wird der Finder angewiesen, das erste Fenster halbtransparent darzustellen. Der Befehl opacity verfügt über zwei Parameter: Der erste Wert (0.7) bestimmt den Grad der Transparenz, wobei 0.1 fast ganz durchsichtig ist und 0.9 wenig Transparenz entspricht. Mit einem Wert von 1 erscheint das Fenster wieder normal. Mit target wird die Nummer des Fensters angegeben. Der Wert von 1 spricht das vorderste Fenster an.
Arbeitet man mit einer Schleife, so lässt sich ein schöner Effekt erzielen. Das Skript
set Transparenz to Nummer / 100
opacity Transparenz target 1
end repeat
end tell
macht das vorderste Fenster des Finders zuerst unsichtbar und blendet es anschließend wieder ganz sanft ein.
Eine praktische Funktion von Apples Programm Mail (und mittlerweile auch Thunderbird) ist die Anzeige der ungelesenen E-Mails im Dock. Der Befehl badge fügt dem Icon eines beliebigen Programms im Dock eine solche Zahl hinzu. Dies kann recht sinnvoll sein, wenn im Hintergrund ein Skript mehrere Kopiervorgänge durchführen soll und mit Hilfe des Icons im Dock die nocht notwendigen Durchgänge angzeigt werden.
|
|
Das Icon eines Programms im Dock kann mit einem numerischen Badge versehen werden. |
Um ein Icon im Dock mit einem solchen Badge zu versehen, wird dem entsprechenden Programm einfach der Befehl badge gefolgt von der anzuzeigenden Zahl übergeben.
badge 100
end tell
Das Icon wird mit dem Befehl restore badge wieder in den Normalzustand versetzt.
restore badge
end tell
Der Poof-Effekt, wenn man ein Icon aus dem Dock zieht, ist immer wieder nett anzusehen. Mit XFun kann dieser Effekt an einer beliebigen Stelle auf dem Bildschirm erzeugt werden. Kombiniert mit zwei Zufallszahlen (eine für die X-, eine für die Y-Achse), lässt sich zum Ende eines Skriptes ein kleines Feuerwerk auf dem Bildschirm abfeiern.
set XAchse to random number 1024
set YAchse to random number 768
poof at {XAchse, YAchse}
end repeat
Innerhalb der Schleife wird zunächst eine zufällige Zahl im Bereich 1 bis 1024 ausgewählt. Dies entsprecht der horizontalen Position auf dem Bildschirm. Dann wird für die vertikale Position eine Zahl ausgewählt. Diese Werte werden in geschweiften Klammern dem Befehl poof übergeben
XFun erweiter AppleScript zwar nicht um dringend benötigte produktive Features, aber die drei Effekte sind einerseits ganz witzig und mit der Transparenz und dem Badge lässt sich bei umfangreichen Skripten, die viele Fenster öffnen und Schleifen abarbeiten, sicherlich die eine oder andere sinnvolle Funktion realisieren.
Im Anhang finden sich eine kleine Sammlung von Links rund um AppleScript, Programme und Tools, die den Einsatz von AppleScript etwas einfacher machen können, sowie eine kleine Übersicht von Skritsprachen, die sich über den Befehl do shell script mit AppleScript kombinieren lassen.
Neben dem Skripteditor und Xcode als die Hauptarbeitsmittel gibt es einige weitere Programme und Tools, die die Entwicklung von Skripten und die Arbeit mit AppleScript erleichtern. Dieser Abschnitt stellt Ihnen ein paar Programme und Lösungen vor.
Mit Appscript wird es möglich, Programme und das System anstelle von AppleScript mit Python anzusprechen und zu steuern. Hierbei werden die Fähigkeiten von Python mit Hilfe einiger Programmier-Bibliotheken ergänzt und so die Brücke zu den so genannten Apple Events, die ja die technische Grundlage von AppleScript darstellen, geschlagen.
Quelle: Webseite des Projektes
Bei der Arbeit an diesem <openbook> erwies sich dieses kleine Programm schnell als unverzichtbar. Seine Aufgabe besteht darin, den Quellcode eines im Skripteditor geöffneten Skriptes in HTML umzuwandeln und dabei die optischen Hervorhebungen beizubehalten.
Quelle: JNSoftware
Die Erstellung einer grafischen Oberfläche für ein Skript mit Hilfe von Xcode und dem Interface Builder kann manchmal etwas zu viel Zeit in Anspruch nehmen. Mit FaceSpan hat Late Night Software schon seit langem eine (kostenpflichtige) Alternative im Angebot, die die Erstellung einer grafischen Oberfläche enorm vereinfacht.
Quelle: Late Night Software
Das Nachrichtensystem Growl bringt von Haus aus auch eine Unterstützung für AppleScript mit. Nachdem das eigene Skript einmal im System von Growl registriert wurde, lassen sich dessen kleinen Nachrichtenfenster aus AppleScript heraus erzeugen.
Quelle: Dokumentation auf growl.info
Das Shareware-Programm erleichtert das Scripting der grafischen Oberfläche enorm und hilft bei der Identifikation der anzusprechenden und zu steuernden Elemente.
Quelle: PreFab
Die Suche nach dem Fehler im Skript wird mit dem Script Debugger von Late Night Software etwas leichter. Das Programm bietet eine Vielzahl von Möglichkeiten, Fehlern auf die Spur zu kommen und kann bei umfangreichen Skripten eine Arbeitserleichterung darstellen.
Quelle: Late Night Software
Mit dem Befehl do shell script ermöglicht AppleScript den direkten Zugriff auf die Console und eröffnet damit ganz neue Möglichkeiten. So lassen sich die Vorteile von AppleScript und die der Arbeit an der Shell recht einfach kombinieren. Bei komplexen Aufgaben kann der Rückgriff auf eine der mit Mac OS X installierten Skriptsprachen angebracht sein. Immerhin sind Python, Perl und Ruby ausgewachsene Programmiersprachen, die bei komplexen Aufgaben schneller ans Ziel führen als die bisweilen doch sehr eigenwillige Syntax von AppleScript. Doch welche Skritsprache soll man lernen, wenn man die Möglichkeiten eines Skriptes der bash ausgereizt hat und nun »größere Kaliber« aufgefahren werden müssen?
Die folgende Liste der unter OS X am Terminal verfügbaren Skriptsprachen ist rein subjektiv! Abweichende Meinungen können gerne in den Kommentaren hinterlassen werden. Die Liste erhebt nicht den Anspruch, jede Skriptsprache, die unter OS X zur Verfügung steht, aufzuführen. So werden alte Veteranen des Commodore AMIGA sich sicherlich noch an A/Rexx erinnern. Die Sprache, obwohl auch für OS X erhältlich, ist hier nicht aufgeführt.
Perl gehört zu den Veteranen unter den Skriptsprachen und verfügt über eine eingeschworene Fan-Gemeinde. Skripten, die in Perl geschrieben wurden, werden in der Regel sehr schnell ausgeführt. Perl verfügt über sehr mächtige reguläre Ausdrücke. Die Lernkurve ist nicht sehr steil und auch der Anfänger kommt recht schnell zu einem Ergebnis. Ein Problem bei der Arbeit mit Perl kann darin bestehen, dass die Grundphilosophie der Sprache (»there is more than one way to do it«) auch einen sehr verschachtelten und schwer zu lesenden Quellcode führen kann. Die schon seit angekündigte Version 6 lässt irgendwie immer noch auf sich warten.
Im Gegensatz zu Perl wird bei Python viel Wert auf einen klar strukturierten Quellcode gelegt. Dies führt unter anderem dazu, dass Skripten in Python auf für Anfänger recht schnell zu erfassen und zu überblicken sind. Generell ist Python vergleichsweise einfach zu lernen und führt ebenso wie Perl zielgerichtet zu Ergebnissen. Für den Einstieg in die Arbeit mit Skripten und generell in die objektorientierte Programmierung ist Python nach meinem Dafürhalten ideal.
Ruby ist mittlerweile eher durch das Projekt Ruby on Rails bekannt. Ebenso wie Python handelt es sich bei Ruby um eine objektorientierte Sprache, die sich auch sehr gut für größere Skripten eignet. Die Lernkurve ist etwas steiler als bei Python, aber mit ein wenig Zeit und Muße kommen auch Anfänger schnell zu brauchbaren Ergebnissen. Indes ist die verfügbare Literatur noch nicht sehr umfangreich und eher auf das Paradepferd Ruby on Rails fixiert. Wer aber einen mächtigen Exoten erlernen will, der liegt mit Ruby allerdings richtig.
Eigentlich wird PHP besser ausschließlich zur Entwicklung von dynamischen Webseiten in Verbindung mit einem Server eingesetzt. Es ist allerdings auch möglich, ein PHP-Skript am Terminal mit dem Befehl php -f gefolgt vom Dateinamen des auszuführenden Skriptes aufzurufen. Verfügt man bereits über umfangreiche Kenntnisse in PHP und nicht über die Zeit, eine andere Skriptsprache zu lernen, dann mag dieses Verfahren eine Lösung darstellen.
Die Sprache Tcl ist unter dem Akronym Tcl/Tk bekannt geworden. Nicht ganz so alt wie Perl, wird Tcl von einer kleineren aber nichts desto trotz umso eingeschworeneren Fan-Gemeinde genutzt. Das Kürzel Tk steht hier für eine spezielle Bibliothek, durch deren Einsatz den Skripten und Programmen eine grafische Oberfläche mitgegeben werden kann. Tcl ist recht leicht zu erlernen, allerdings ist auch hier wie bei Ruby die verfügbare Einstiger-Lektüre nicht sehr umfangreich.
Der Einsatz der Sprache awk in Verbindung mit dem Streamline-Editor sed ist dann angeraten, wenn umfangreiche Text-Dateien manipuliert werden müssen. Dies kann beispielsweise bei statistischen Daten, die in einer Textdatei mit Semikolon getrennt gespeichert wurden, angebracht sein. awk und sed beruhen auf dem extensiven Einsatz von regulären Ausdrücken, so dass man neben viel Geduld und Ruhe auch Motivation für abstraktes Denken mitbringen sollte. Hat man beide aber einmal gelernt, dann steht der Manipulation von umfangreichen Texten etwa in Kombination mit einer statistischen Auswertung oder der Anpassung von Konfigurations-Dateien nicht mehr im Wege.
Zu AppleScript gibt es eine wenn auch kleine so doch aktive und rege Fan- und Entwicklergemeinde. Diese kleine Übersicht von Webseiten ist Ihnen bei der eigenen Recherche und Suche nach Lösungen möglicherweise eine kleine Hilfe.
AppleScript Sourcebook
1996 von Bill Chesemann gegründet und mittlerweile unter der Ägide von MacScripter stehend bietet das Sourcebook eine umfangreiche Sammlung von Antworten auf gängige Fragen der Programmierung mit AppleScript.
Fischer-Bayern
Hier findet sich unter anderem das einführende Tutorial AppleScript für absolute Starter sowie das umfangreichste deutschsprachige Forum zu AppleScript.
hohabadu
H=:o)LGI bietet auf seiner Webseite eine Sammlung an nützlichen Tipps, Tricks und Routinen, Links und Literaturhinweisen.
The FooDoo Lounge
Richard Morton sammelt in seiner FooDoo Lounge Code-Schnipsel, Sub-Routinen und weitere Informationen rund um AppleScript.
Jon's Little Page of AppleScripts
Die Webseite bietet eine umfangreiche Sammlung von eigenen Skripten des Autors, die kostenfrei herunter geladen werden können.
MacScripter
MacScripter ist die zentrale Anlaufstelle. Neben einem gut frequentierten Forum finden sich jede Menge Beispiele und Code-Schnipsel.
osaxen.com
Bei osaxen.com ist das zentrale Verzeichnis für Scripting Additions angesiedelt.
The Development of AppleScript (PDF)
In seinem 32 Seiten langen Aufsatz schreibt William R. Cook, ein ehemaliger Mitarbeiter on Apple und jetzt Professor für Informatik, die Geschichte von AppleScript von der Idee bis zur Realisierung.