{"id":124,"date":"2020-11-08T13:51:49","date_gmt":"2020-11-08T13:51:49","guid":{"rendered":"https:\/\/www.unleserlich.info\/?p=124"},"modified":"2021-01-03T13:06:06","modified_gmt":"2021-01-03T13:06:06","slug":"scriptable-tutorial-teil-2","status":"publish","type":"post","link":"https:\/\/www.unleserlich.info\/?p=124","title":{"rendered":"Scriptable Tutorial Teil 2 &#8211; Dateien"},"content":{"rendered":"\n<p>Im <a href=\"https:\/\/www.unleserlich.info\/?p=81\" data-type=\"post\" data-id=\"81\">ersten Teil des Tutorials<\/a> haben wir uns angesehen, wie mit Scriptable ein iOS-Widget erstellt werden kann. In diesem Tutorial soll es nun um das Thema Persistenz gehen. Wie ist vorzugehen, wenn ein Script Daten zwischenspeichern muss?<\/p>\n\n\n\n<p>Scriptable erlaubt Euch leider keinen einfachen Zugriff auf Datenbanken oder Propertyspeicher. Technologien, die Ihr vielleicht aus dem Web kennt, k\u00f6nnen in Scriptable also nicht verwendet werden. Gl\u00fccklicherweise gibt es einen leichten Ausweg. Ihr k\u00f6nnt mittels der Scriptable-API Dateien im Dateisystem des Smartphones erzeugen, diese Dateien bleiben auch nach dem Ausf\u00fchren eines Scripts erhalten und k\u00f6nnen so beim n\u00e4chsten Scriptlauf wieder eingelesen werden.<\/p>\n\n\n\n<h5>Die Beispielapplikation &#8211; Instagram Followers v2<\/h5>\n\n\n\n<p>Im <a href=\"https:\/\/www.unleserlich.info\/?p=81\" data-type=\"post\" data-id=\"81\">ersten Teil dieses Turorials<\/a> haben wir ein Widget erstellt, welches die aktuelle Anzahl an Followern zu einem Instagram-Account anzeigt. Dieses wollen wir nun im zweiten Teil des Tutorials erweitern. Zus\u00e4tzlich zur aktuellen Anzahl an Followern soll die Steigerung der Follower zu gestern, letzter Woche und letztem Monat dargestellt werden. So wird das Endergebnis am Ende aussehen:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" src=\"https:\/\/www.unleserlich.info\/wp-content\/uploads\/2020\/11\/Bildschirmfoto-2020-11-07-um-16.45.41.png\" alt=\"\" class=\"wp-image-126\" width=\"137\" height=\"142\" srcset=\"https:\/\/www.unleserlich.info\/wp-content\/uploads\/2020\/11\/Bildschirmfoto-2020-11-07-um-16.45.41.png 472w, https:\/\/www.unleserlich.info\/wp-content\/uploads\/2020\/11\/Bildschirmfoto-2020-11-07-um-16.45.41-291x300.png 291w\" sizes=\"(max-width: 137px) 100vw, 137px\" \/><figcaption>Das Endergebnis dieses Tutorials<\/figcaption><\/figure><\/div>\n\n\n\n<h5>Verwendete API&#8217;s<\/h5>\n\n\n\n<p>Im Vergleich zum <a href=\"https:\/\/www.unleserlich.info\/?p=81\" data-type=\"post\" data-id=\"81\">ersten Tutorial<\/a> ben\u00f6tigen wir nur eine weitere Klasse aus der Scriptable API:<\/p>\n\n\n\n<ul><li><a href=\"https:\/\/docs.scriptable.app\/filemanager\/\">FileManager<\/a>: Klasse, welche s\u00e4mtliche Methoden zum Lesen und Schreiben des Dateisystems bereitstellt.<\/li><\/ul>\n\n\n\n<h5>Ausz\u00fcge aus dem Code<\/h5>\n\n\n\n<p>Der FileManager stellt zwei unterschiedliche Methoden zur Verf\u00fcgung, um auf das Dateisystem zuzugreifen:<\/p>\n\n\n\n<ul><li>.local: Erstellt eine Datei im lokalen Dateisystem im Kontext der Scriptable App<\/li><li>.iCloud: Erstellt eine Datei im iCloud-Berech der Scriptable App<\/li><\/ul>\n\n\n\n<p>Beide Methoden geben eine Instanz des FileManagers zur\u00fcck, mit welcher dann im Folgenden weitergearbeitet werden kann. Wir werden im Folgenen mit der iCloud-Variante arbeiten. Dies hat den charmanten Vorteil, dass wir \u00fcber den PC direkt die vom Widget erstellten Dateien \u00fcberpr\u00fcfen k\u00f6nnen, sofern wir von diesem Zugriff auf die iCloud haben. Bei einer Dateiablage im lokalen Dateisystem des Smartphones w\u00e4re dies nicht ohne weiteres m\u00f6glich.<\/p>\n\n\n\n<p>Das Einlesen bzw. Schreiben von Dateien funktioniert f\u00fcr beide Varianten vollkommen identisch, es gibt nur eine Ausnahme. Soll auf eine Datei aus der iCloud zugegriffen werden, kann es sein, dass diese lokal noch nicht vorhanden ist. In diesem Fall muss die Datei erst aus der iCloud heruntergeladen werden. Dies geschieht \u00fcber die Methode<\/p>\n\n\n\n<ul><li>downloadFileFromiCloud: \u00dcbergeben werden muss hier mindestens ein Dateiname oder auch der Pfad zu einer Datei.<\/li><\/ul>\n\n\n\n<p>Sofern Ihr das Widget nur auf einem Endger\u00e4t nutzt, ist nach der Anlage sichergestellt, dass die Datei lokal und in der iCloud vorhanden ist. W\u00fcrdet Ihr aber mit zwei Smartphones das Widget betreiben, w\u00e4re die Datei auf dem zweiten Smartphone nicht sofort vorhanden und ein downloadFileFromiCloud w\u00e4re vor dem ersten Zugriff erforderlich.<\/p>\n\n\n\n<p>Wie legt man nun eine neue Datei an? Zun\u00e4chst einmal wollen wir die Followerstatistik nicht direkt im Hauptverzeichnis von Scriptable ablegen, sondern f\u00fcr unser Widget ein eigenes Unterverzeichnis nutzen. Dieses Verzeichnis wird wie folgt angelegt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>let&nbsp;dir&nbsp;=&nbsp;fm.documentsDirectory();\nvar&nbsp;path&nbsp;=&nbsp;fm.joinPath(dir,&nbsp;\"insta\/\");\nif&nbsp;(!fm.fileExists(path))&nbsp;{\n&nbsp;&nbsp;&nbsp;fm.createDirectory(path,&nbsp;false);\n}<\/code><\/pre>\n\n\n\n<p>Folgende Methoden des Filemanagers werden verwendet:<\/p>\n\n\n\n<ul><li>.documentsDirectory: Gibt den Pfad der Scriptable App zur\u00fcck.<\/li><li>.joinPath: Methode, um den Pfad um eigene Verzeichnisse zu erg\u00e4nzen.<\/li><li>.fileExists: Pr\u00fcft, ob ein Verzeichnis oder eine Datei bereits existiert.<\/li><li>.createDirectory: Legt ein Verzeichnis an.<\/li><\/ul>\n\n\n\n<p>Nachdem wir nun einen Speicherort haben, m\u00fcssen wir in diesem nur noch eine Datei anlegen. Dies geschieht wie folgt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>path&nbsp;+=&nbsp;accountName&nbsp;+&nbsp;\".json\";\nfm.writeString(path,&nbsp;JSON.stringify(followers));<\/code><\/pre>\n\n\n\n<p>Zun\u00e4chst erg\u00e4nzen wir in diesem Beispiel den verwendeten Pfad noch um einen Dateinamen. F\u00fcr unser Widget verwenden wir den Namen des Instagram Accounts. Theoretisch k\u00f6nnte das Widget auf einem Endger\u00e4t f\u00fcr mehr als einen Account eingerichtet werden. Durch die Verwendung des Dateinamens wird sichergestellt, dass sich die verschiedenen Wigets nicht gegenseitig die Daten \u00fcberschreiben. <\/p>\n\n\n\n<p><em>Wichtig: .writeString erzeugt die Datei, die zu beschreiben ist. Falls die Datei bereits vorhanden ist, wird diese \u00fcberschrieben!<\/em><\/p>\n\n\n\n<p>Lesen k\u00f6nnen wir die Datei analog dem schreibenden Zugriff wie folgt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>var jsonString = fm.readString(path);<\/code><\/pre>\n\n\n\n<p>Vor dem Lesen der Datei sollte immer mit .fileExists gepr\u00fcft werden, ob die Datei auch wirklich existiert, da ansonsten eine Exception auftreten wird.<\/p>\n\n\n\n<h5>Das restliche Handwerk<\/h5>\n\n\n\n<p>Nachdem nun die Grundlagen zum Lesen und Schreiben von Dateien vorhanden sind, hier nur ein kurzer Abriss \u00fcber das Erfassen der Statistiken.<\/p>\n\n\n\n<p>Jede erfasste Followerzahl wird mit Timestamp in einem Datenobjekt abgelegt. Dieses Datenobjekt wird bei Beendigung des Widgets als JSON in eine Datei weggespeichert und beim Start des Widgets dann entsprechend wieder eingelesen. So w\u00e4chst \u00fcber die Zeit der verf\u00fcgbare Datenstamm an Followerdaten an. Hieraus folgt nat\u00fcrlich auch, dass beim ersten Start des Widgets noch keine Ver\u00e4nderung zum Vortag angezeigt werden kann, dies wird dann erst am Folgetag klappen. Gleiches gilt nat\u00fcrlich auch die w\u00f6chentliche und monatliche Statistik, die erst mit entsprechender Zeitverz\u00f6gerung verf\u00fcgbar sein werden.<\/p>\n\n\n\n<h5>Zum Abschluss<\/h5>\n\n\n\n<p>Sollte Euch mein kleines Scriptable Tutorial gefallen haben, w\u00fcrde ich mich \u00fcber einen kleinen Einwurf in die Kaffeekasse freuen:<\/p>\n\n\n\n<p><a href=\"https:\/\/www.paypal.com\/paypalme\/markmescher\/2,99\">https:\/\/www.paypal.com\/paypalme\/markmescher\/2,99<\/a><\/p>\n\n\n\n<p>Wie gro\u00df der Kaffee werden soll, d\u00fcrft Ihr nat\u00fcrlich frei entscheiden \ud83d\ude42<\/p>\n\n\n\n<p>Den vollst\u00e4ndigen Programmcode findet Ihr hier:<\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/bestmacfly\/Sriptable-Instagram-Follower-Widget\">https:\/\/github.com\/bestmacfly\/Sriptable-Instagram-Follower-Widget<\/a><\/p>\n\n\n\n<p>Solltet Ihr Anregungen zu diesem Tutorial haben, freue ich mich \u00fcber Eure Kommentare!<\/p>\n\n\n\n<p>Weiter geht es mit dem Tutorial direkt im dritten Teil, sprecht mit Siri:<\/p>\n\n\n\n<p><a href=\"https:\/\/www.unleserlich.info\/?p=154\" data-type=\"post\" data-id=\"154\">Scriptable Tutorial Teil 3 \u2013 Hey Siri<\/a><\/p>\n\n\n\n<p>Auch hier noch einmal der Hinweis auf weitere sinnvolle Informationsquellen:<\/p>\n\n\n\n<p><a href=\"https:\/\/www.scriptables.de\">https:\/\/www.scriptables.de<\/a><\/p>\n\n\n\n<p>Auf dieser Seite findet Ihr unz\u00e4hlige Beispielscripte, die Ihr direkt nutzen und als Anregung verwenden k\u00f6nnt.<\/p>\n\n\n\n<p>F\u00fcr Fragen aller Art bietet sich folgende Seite an:<\/p>\n\n\n\n<p><a href=\"https:\/\/talk.automators.fm\/\">https:\/\/talk.automators.fm\/<\/a><\/p>\n\n\n\n<p>Es lassen sich auch hier hunderte Beispiele finden, die nur darauf warten, ausprobiert zu werden. Auch wird Euch hier gerne bei Problemen weitergeholfen.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Im ersten Teil des Tutorials haben wir uns angesehen, wie mit Scriptable ein iOS-Widget erstellt werden kann. In diesem Tutorial soll es nun um das Thema Persistenz gehen. Wie ist vorzugehen, wenn ein Script Daten zwischenspeichern muss? Scriptable erlaubt Euch leider keinen einfachen Zugriff auf Datenbanken oder Propertyspeicher. Technologien, die Ihr vielleicht aus dem Web\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.unleserlich.info\/?p=124\">Weiterlesen &raquo;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":112,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"twitterCardType":"","cardImageID":0,"cardImage":"","cardTitle":"","cardDesc":"","cardImageAlt":"","cardPlayer":"","cardPlayerWidth":0,"cardPlayerHeight":0,"cardPlayerStream":"","cardPlayerCodec":""},"categories":[16,19],"tags":[11,9,15,14,12,17,10],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/www.unleserlich.info\/index.php?rest_route=\/wp\/v2\/posts\/124"}],"collection":[{"href":"https:\/\/www.unleserlich.info\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.unleserlich.info\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.unleserlich.info\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.unleserlich.info\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=124"}],"version-history":[{"count":17,"href":"https:\/\/www.unleserlich.info\/index.php?rest_route=\/wp\/v2\/posts\/124\/revisions"}],"predecessor-version":[{"id":240,"href":"https:\/\/www.unleserlich.info\/index.php?rest_route=\/wp\/v2\/posts\/124\/revisions\/240"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.unleserlich.info\/index.php?rest_route=\/wp\/v2\/media\/112"}],"wp:attachment":[{"href":"https:\/\/www.unleserlich.info\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=124"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.unleserlich.info\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=124"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.unleserlich.info\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=124"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}