Neues Turnier in Zülpich-Enzen

NeOnAlert – los gehts!

Wie? Was Wo?? Hier lang: NeOnALERT geht in den Betatest!

IMG_1635

Apple Swift // Dropbox Core API

Seit zwei Wochen lerne ich die Programmiersprache Swift und veröffentliche hier direkt mal mein erstes Tutorial. Und das, weil es zum hier behandelten Thema schlicht noch keins gibt 😉 Dropbox hat die beiden APIs “Dropbox Sync API” und “Dropbox Datastore API” aufgekündigt und stellt Mitte nächsten Jahres den Support dafür ein. Der Nachfolger, die “Dropbox Core API” steht schon in den Startlöchern und bot mir die Gelegenheit, direkt mit der neuen API anzufangen. Als Swift Neuling und im Bereich Dropbox ebenso Unwissender, hat mich das mal flockig einen ganzen (Urlaubs-) Freitag gekostet. Aber hier ist nun das Ergebnis 😉

Sinn und Zweck der Implementierung der Dropbox Core API ist es, Dateien aus einer (noch zu schreibenden) App unkompliziert vom lokalen Storage des Endgeräts (iPhone/iPod/iPad) auf den PC zu bekommen. Und da bietet sich ja (natürlich unter anderem) die Dropbox an. Und warum nicht die iCloud? Nun, weil die Dropbox für mich als Anfänger viel leichter zu handhaben ist und weil ich in meinem dicken Buch (s.u.) noch keinen Weg gefunden habe, wirklich “Dateien” auf dem iCloud Drive zu speichern. Und das ist mit der Dropbox möglich.

Das hier wird kein Tutorial, welches Dich in die Programmiersprache Swift oder in die Entwicklungsumgebung XCode einführt. Dazu kann ich Dir nur die beiden genialen Bücher “Durchstarten mit Swift” von Stefan Popp und Ralf Peters [www.swiftbuch.de] sowie das 800 Seiten starke Kompendium “iOS8 App Development Essentials” von Neil Smyth [www.techotopia.com] empfehlen. [Aber Vorsicht – beide Bücher haben einen hohen Suchtfaktor!] Wenn ich also später schreibe, dass wir eine “Action” eines Buttons mit einer Methode verknüpfen, dann gehe ich mal davon aus, dass Du weiß, wie das geht.

Des Weiteren möchte ich noch kurz darauf hinweisen, dass ich selbst Swift noch erlerne und bei Weitem noch nicht alle Facetten der Sprach erfasst habe. Wenn ich also Form- oder Verfahrensfehler begehe, so bitte ich das zu entschuldigen und würde mich über entsprechende Hinweise freuen.

So, jetzt gehts los! Als erstes legt man bei Dropbox eine neue App an. Das lässt sich über den Dropbox Developer Bereich erledigen. Einfach “Create App” klicken, anschließend “Dropbox API App” auswählen und die gewünschte Berechtigung auswählen. Für mein Projekt reicht “Yes! My app only needs access to files it creates.” Zu guter Letzt brauchts noch einen schmissigen Namen für die App und der Klick auf “Create App” erledigt den Rest. Das nun folgende Formular kann man vorerst fast vollständig ignorieren – für uns sind nur der App Key und das App Secret interessant.

Als nächstes laden wir die Dropbox Core API herunter und entpacken das Archiv an einem Ort, den wir auch wiederfinden. Jetzt können wir XCode starten und ein neues Projekt aus dem Template “Single View Application” erzeugen. Als Name nehme ich einfach mal “dropboxCoreAPI”, als Sprache Swift, und als Target ein iPhone. CoreData benötigen wir nicht – außer in der Dropbox wollen wir keine Daten persistieren (ich mag dieses Wort!).

Sobald das Projekt erstellt ist, ziehen wir den eben entpackten Ordner “DropboxSDK.framework” in den Projektbaum und lassen ihn an “zweiter Stelle” los. Wichtig ist der Haken bei “Copy Files if needed” im folgenden Dialog. Jetzt steht die Dropbox Core API in unserem Projekt zur Verfügung. Zumindest fast. Wir müssen in den Projekteinstekllungen unter “Build Phases -> Link Binary With Libraries” noch zwei Frameworks hinzufügen: das “Security.framework” und das “QuartzCore.framework” – dies lässt sich über das “+” erledigen.

Jetzt kommt der Teil, der mich bei meinen Versuchen ziemliche Nerven gekostet hat: wir brauchen einen Bridging Header! Da es sich bei der API um ein (so vermute ich mal) Objective-C Framework handelt, stehen die exportierten Typen, Properties und Methoden nicht sofort in Swift zur Verfügung. Daher muss man einen so genannten Bridging Header einfügen, der die Objectiv-C Bibliotheken mit Swift koppelt. Das lässt sich relativ leicht bewerkstelligen – man muss halt nur wissen, dass man es tun muss 😉 Also, eine neue Datein anlegen, als Typ “Objective-C File” wählen, die Datei “temp” nennen, speichern und im nun folgenden Dialog bestätigen, dass man einen Bridging Header anlegen möchte. Anschließend kann man die temp.m direkt wieder löschen – sie wird nicht mehr gebraucht.

Der gerade automatisch erzeugten Datei dropboxCoreAPI-Bridging-Header.h fügen wir eine einzelne Zeile Code hinzu und binden damit die Dropbox Core API ein:

Jetzt, wo das Framework zur Verfügung steht, geht es Schlag auf Schlag. Im nächsten Schritt erweitern wir unsere ViewController Klasse um zwei Properties:

An dieser Stelle sei schon mal darauf hingewiesen, dass ich das neue Protokoll DBRestClientDelegate zur Klassendefinition hinzugefügt habe. Diese Erweiterung benötigen wir später, wenn wir die Klasse zum Delegaten des RestClients machen.

Nun benötigen wir in unserer Klasse noch drei Methoden, die die Dropbox Verbindung einrichten, herstellen und trennen können. Außerdem habe ich noch drei Konstanten hinzugefügt, die den eingangs erwähnten App Key und das App Secret unserer Dropbox App enthält. Solltest Du dir die nicht notiert haben, so kannst Du diese Informationen jederzeit im Developer Bereich raussuchen. Unser fast fertiger ViewController sieht dann so aus:

Damit unsere Dropbox Sitzung initialisiert wird, fügen wir nun die setupDropbox() Methode der ViewDidLoad() Methode hinzu:

Für Spaß können wir unsere Projekt jetzt einfach mal im iOS Simulator starten und werden nicht sonderlich erstaunt sein, dass in der Log Ausgabe von XCode zu lesen ist:
2015-04-25 09:51:24.938 dropboxCoreAPI[2051:214105]
Nicht mit Dropbox verbunden :(

Aber das ist ja auch schon mal eine Erkenntnis.

Nun legen wir uns zwei Buttons an und verbinden diese mit dem ViewController. In den Actions rufen wir dann einmal die Methode zum Herstellen und einmal die Methode zum Trennen der Dropbox Verbindung auf:

Die Methode linkDropboxSession erwartet als Parameter einen ViewController, in dem der Dropbox Login Dialog angezeigt werden kann, sofern die Dropbox App nicht installiert ist. Da übergeben wir einfach mit self den aktiven ViewController.

Bevor wir unsere App nun im Simulator starten, müssen wir noch ein URL Schema hinzufügen. Dieser Mechanismus erlaubt es, nach erfolgter Anmeldung an der Dropbox wieder zurück zu unserer App zu finden. Das URL Schema setzt sich aus dem Präfix db- und Deinem App Key zusammen. In diesem Beispielprojekt lautet es db-wkv...DEIN_APP_KEY...1tu. Das Schema wird in den Projekteigenschaften unter “Info -> URL Types” eingetragen. Dort mit “+” einen neuen Typen erzeugen und das Feld “URL Scheme” befüllen. Der Rest kann leer bleiben.

Zur Sicherheit würde ich jetzt den iOS Simulator über “Reset Content and Settings” mal aufräumen. Dadurch ist sichergestellt, dass die App “sauber” und mit dem richtigen URL Schema gestartet wird.

Startet man die App nun im Simulator und klickt auf den Button zum Verbinden, so erscheint der Dropbox Login Dialog. An dieser Stelle aber bitte noch nicht anmelden, sondern abbrechen. Denn unserer App fehlt noch eine Methode, die den Rücksprung aus der Dropbox Anmeldung in unsere App behandelt. Probiert man es doch, so erhält mal folgende Fehlermeldung im XCode Log:
2015-04-25 10:17:28.609 dropboxCoreAPI[2348:295792] [ERROR] DropboxSDK:
app delegate does not implement application:openURL:sourceApplication:annotation:

Na, dann wollen wir das doch mal implementieren! Dazu fügen wir der Datei AppDelegate.swift die folgende Methode ein. Diese behandelt den Zustand, wenn unsere App “von außen” über das URL Schema aufgerufen wurde. Wir überprüfen in dieser Methode einfach mal, ob die Verbindung hergestellt wurde und geben das im Log aus:

Startet man nun die App und klickt auf den Button zum Verbinden, landet man wie eben auch in der Dropbox Anmeldemaske. Diesmal füllen wir diese aus, klicken “Login and link” und stellen somit (sofern wir alles richtig gemacht haben) eine dauerhafte Verbindung zwischen der App (auf diesem Gerät) und der Dropbox her. Das XCode Log sollte das entsprechend quittieren.
2015-04-25 10:28:15.090 dropboxCoreAPI[2404:326667]
Dropbox Verbindung hergestellt!

Und nu? Wir könnten die Verbindung nun wieder trennen und überprüfen, ob der Mechanismus auch funktioniert. Und dann wieder verbinden und wieder trennen usw… bis Pflaumenpfingsten.

Schöner wäre es sicherlich, wenn wir auch eine Datei hochladen könnten. Dazu brauchen wir einen Button und drei neue Methoden auf/in unserem ViewController:

Zuerst erzeugen wir im lokalen Dokumentenspeicher der App eine Textdatei und befüllen sie mit ein wenig Text. Anschließend beauftragen wir den RestClient mit dem Upload. Da der Upload asynchron abläuft, benötigen wir zwei Methoden, die Erfolgs- und Fehlerfall abfangen und behandeln. Aus diesem Grund muss der ViewController als Delegat des RestControllers agieren. Dies haben wir schon ziemlich am Anfang durch das Hinzufügen des entsprechenden Protokolls zum Klassendefinition erledigt:

Startet man nun die App und klickt bei zuvor hergestellter Dropbox Verbindung auf den Button zum Hochladen, so erscheint wie von Geisterhand eine neue Textdatei im App-Ordner der Dropbox.

Mission erfüllt!

Bild

NEONALARM 2015

iOS 8 App Development