Wir haben gerade die neue Bugfix-Version 3.0.3 veröffentlicht. Eigentlich ist das nichts Spektakuläres: Wir finden einen Fehler oder bekommen einen gemeldet, wir suchen und finden eine Lösung. Ärger, Ehrgeiz entwickeln, kindische Freude. Das normale Gefühlsleben eines Softwareentwicklers.

Eigentlich könnte die Welt so schön einfach sein: Entwickeln, neue Version erstellen, einen Knopf drücken und veröffentlichen. Tatsächlich funktionierte das bisher ziemlich reibungslos vor allem bei der Web-Version. Ein paar juristische Sachen, wie Datenschutz und Impressum gilt es zu beachten, aber sonst ist diese Veröffentlichung eine Sache von wenigen Minuten. Selbst die Android-Version geht inzwischen relativ fix, auch wenn Google immer wieder mit der einen oder anderen neuen, teils sehr frustrierenden, Schikane um die Ecke kommt. Aber dank einer deutlich reduzierten Bauzeit von nur noch 1-2 min entgegen der 15-20 min noch vor einem Jahr, ist eine neue Testversion oder auch die finale Version relativ fix erstellt. Und dann kommt die iOS-Version.

Dieser Beitrag soll einmal eine andere Seite aufzeigen, die wir normalerweise nur intern in unser Team hinein fressen. Denn es ist bei weitem nicht alles immer Friede, Freude, Eierschecke. In meinem konkreten Fall handelt die Geschichte von unserer iOS-Version, die zunehmend zur Last zu werden droht.

Es ist leider zur Regel geworden, dass Apple Probleme macht. Dabei geht es weniger um irgendwelche neuen Restriktionen im AppStore; die gibt es, wie beschrieben, bei Google in gleichem frustrierenden Maße. Ich erzähle es euch anhand von zwei konkreten Beispielen, die die Veröffentlichung der Versionen 3.0.x erschwerten.

Die Hardware

Als wir nach fast einem Jahr Entwicklung der neuen Version 3.0 soweit in den Startlöchern standen, war klar, dass wir noch die iOS-Variante prüfen mussten. Wie wir schon mehrfach sagten, wir sind nur Android-Entwickler und somit ist es fast unmöglich für unser Team, parallel auch an der iOS-Variante zu arbeiten. Das scheitert im Wesentlichen schon an der benötigten Hardware, einem MacBook. Nur ich selbst verfüge über ein sehr altes Modell, dass ich einst von euren Spendengeldern finanzierte. Und dieses fuhr ich hoch. Als ich die neue Version erstellt hatte, wie ich es immer tat, kam plötzlich der AppStore mit folgender Meldung um die Ecke:

Die App muss mindestens für die iOS-Version 11 gebaut werden.

Das passiert hin und wieder, auch aufseiten von Google. Also stelle ich intern etwas um und versuche es erneut. Und damit wurde eine Kettenreaktion ausgelöst: Der neue Standard konnte nur mit der neuen XCode-Version 14.1 erstellt werden. XCode ist das unumgängliche Werkzeug, das notwendig ist, zur Erstellung der Apps und der Grund, warum das alles überhaupt auf einem Mac durchführen muss. Nun stellte sich aber heraus, dass auf meinem Mac besagte XCode-Version nicht installierbar war. Denn mein MacOS war zu alt. Tief durchatmen und weiter. Ich versuchte also, das MacOS zu updaten, das soll ja Apple-Freunden nach immer so einfach und problemlos verlaufen. Pustekuchen, denn MacOS 13.6 weigerte sich beharrlich, installiert zu werden und brach stets ohne weitere Fehlermeldung die Installation ab. Es stellte sich nach vielen Stunden heraus, dass mein MacBook Air zu alt ist!

Das muss man sich mal auf der Zunge zergehen lassen: Apples AppStore zwingt mich im Endeffekt, ein neues MacBook zu kaufen, damit ich meine kostenlose OpenSource-Software bei denen hochladen kann! Das ist aus mehrererlei Sicht nicht nachvollziehbar, weil ich mich weigere, ein eigentlich funktionierendes Gerät auszusondern und andererseits, weil ich gezwungen bin, sauteure Hardware kaufen zu müssen. Es ist ja nicht so, als gäbe es in der Apple-Welt günstige Varianten.

Ich hatte dem Team schon geschrieben und angekündigt, dass ich aktuell nicht gewillt bin, so viel Geld auszugeben und die iPhones wohl nicht länger mit Updates beliefert würden. Doch ein wenig Ehrgeiz hatte ich dann doch entwickelt und fand irgendwo in den Ecken des Internets doch eine Möglichkeit, das neue MacOS zu installieren. Jetzt hängt an meinem MacBook Air dauerhaft ein USB-Stick dran, von dem das Betriebssystem gestartet wird.

Ich kann nicht sagen, wie lange dieses Provisorium halten wird, aber ich kann sagen, dass wir nicht genügend Spenden reinbekommen, um es uns leisten zu können, mal eben ein funktionstüchtiges Gerät zu ersetzen. Was also danach kommt, weiß ich nicht. Man darf ja auch nicht vergessen, dass Apple noch zusätzliche Kosten verlangt, im Gegensatz zu Google. Wir müssen jährlich $100 zahlen, um überhaupt irgendwas in deren AppStore publizieren zu dürfen – unabhängig davon, ob es Freeware ist oder nicht (was sie auch nicht davon hält, dann von den kostenpflichtigen Apps nochmal den gleichen Prozentsatz abzuziehen, wie auch Google). Und das alles, obwohl wir alle gar kein iPhone haben und uns das alles eigentlich ziemlich egal sein könnte.

Die Software

Als dann alles wieder so weit lief, machte ich mich also an das Erstellen der neuen Version. Die Handgriffe sitzen inzwischen, ich weiß, wo ich was auswählen muss – und ich weiß, dass der gesamte Prozess pro Version immernoch etwa 15 min dauert. Die Wartezeiten für die initialen Checks im AppStore nicht mit eingerechnet. Es treten immer wieder komische Fehler auf. Diese sind eigentlich der Grund, warum wir immer so lange zögern, die iPhone-Version zu prüfen: Wir wollen sicher sein, dass funktional aufseiten unseres Codes alles so läuft, wie wir uns das vorstellen, bevor wir uns um iOS-spezifische Probleme kümmern. Und wir wollen dabei vermeiden, dies häufiger als notwendig zu tun, weil seltsame Fehler völlig zufällig auftreten. Was gestern ging, muss nicht zwangsläufig heute auch funktionieren.

Exakt so war es gestern nachmittag, als ich mich entschied, die eigentlich sehr kleine Bugfix-Version zu veröffentlichen. Es gab nur sehr geringfügige Änderungen am Code, absolut nichts, was auf irgendeine Art und Weise auch nur entfernt einen anderen Einfluss auf das Betriebssystem hatte, als die Version, die vorher erstellt wurde. Gar nichts. Doch es tauchten Fehler auf:

Stored properties cannot be marked potentially unavailable with ‚@available‘

Ich habe absolut keine Ahnung, was das bedeuten soll. Also rein damit in die Suchmaschine. Wie sich dabei eigentlich immer heraus stellt: Der Fehler hat nichts mit dem zu tun, was wir direkt beeinflussen können. Es handelt sich nicht um einen klassischen Programmierfehler, nichts, wo man sagt: Oh, da haben wir eine Klammer vergessen, ja ergibt Sinn. Nein, dieser Fehler scheint bei tausenden Leuten auf der ganzen Welt völlig aus dem Nichts aufzutauchen und auf einschlägigen Webseiten werden Lösungsversuche noch und nöcher orakelt. Und weil eine davon so unverständlich wie die andere ist, kann ich nichts anderes tun, als eine nach der anderen einfach blind durchzuprobieren. Irgendwann klappte eine. Solche Erkenntnisse speichere ich dann gewöhnlich bei uns intern in einem „Cheat Sheet“ ab. Dann lief es wieder – ein paar Minuten lang:

Command PhaseScriptExecution failed with a nonzero exit code

Ich kann damit in etwa so viel anfangen, wie mit der Aussage vorher. Der Unterschied zu dem Fehler vorher ist: Es gibt NOCH viel mehr obskure Lösungsansätze im Internet. Und das bedeutete: Es dauerte noch viel länger, sie alle durchzuprobieren. Das geht vom klassischen Neustart bis hin zu komplexen Eingriffen in irgendwelche Interna vom Compiler oder gar des Betriebssystems. Die Leute im Internet schreiben scheinbar völlig willkürlich, was denen so einfällt und dass ihnen dies oder jenes geholfen hätte, oft mich den klaren Aussagen, dass sie das eigentlich auch nicht verstehen und nur die Lösung nachplappern die ein anderer Typ auf der anderen Seite des Internets gepostet hatte. Und nahezu überall stehen bis zu hunderten von Daumen hoch und Daumen runter dran. Was am Ende warum hilft, das ist nicht klar. Klar ist nur, dass alles manchmal hilft und manchmal nicht und dass man nicht allein ist, es sich somit nicht um ein spezielles Problem des eigenen Projektes handelte.

Das Problem hierbei ist tatsächlich, dass man weder mit der Fehlermeldung selbst noch mit den Lösungsansätzen irgendwie eine gewisse Erkenntnis erlangt. Es ist nicht so, dass man das Gefühl bekommt, etwas zu lernen. Man lernt nicht, was konkret falsch gelaufen ist, was man zukünftig tun muss, um das zu vermeiden. Die Änderungen erscheinen vollkommen willkürlich, ich habe sogar Angst, dass die schlussendlich scheinbar funktionierende Möglichkeit nicht intern etwas so zerschießt, dass irgendwas in der App nicht mehr so funktioniert, wie es gedacht ist. Geht die Ortung noch? Können wir noch Dateien speichern? Ich kann das letztlich am Ende nur stichprobenartig durchprobieren und hoffen, dass erstens der AppStore die App nicht aus ominösen Gründen ablehnen wird, dass zweitens alles ordnungsgemäß läuft und dass drittens der Fehler nicht mehr auftritt zukünftig – oder gar zu neuen Fehlern dieser Art führt.

Klar treten auch sonst hin und wieder komische Fehler auf, auch bei der Android-Entwicklung. Doch mir ist es noch nie passiert, dass ich nicht irgendwann verstanden habe, was das Problem war, was die Fehlermeldung mir sagen wollte und warum am Ende die Lösung so funktionierte wie sie es tat. Meinen Teammitgliedern trichtere ich immer ein: Wenn ihr ein Bug fixt, dann möchte ich, dass ihr versteht und mir erklären könnt, warum euer Fix funktioniert und warum der Code ohne diesen Fix nicht das gewünschte Verhalten aufwies. Das ist essenziell um zukünftig ähnliche Fehler zu vermeiden, das gehört zum Lernprozess. Ich selbst halte mich strikt daran: Fixes, die ich aus dem Internet kopiere, checke ich erst dann ein, wenn ich wirklich vollends verstanden habe, was sie tun. Das scheint mir aber bei diesen iOS-spezifischen Problemen gänzlich unmöglich. Und das liegt nicht an meiner eigenen Beschränktheit oder meinen wirklich vorhandenen Berührungsängsten mit der Apple-Welt, sondern das zeigt einfach die Masse der Forenteilnehmer und die tausenden völlig unterschiedlichen Lösungen, die eigentlich nur eine Sache gemeinsamen: Sie haben nie eine Erklärung, sie nennen immer nur das potentielle Wie, nie das Warum. Es scheint keine Logik hinter solchen Fehlermeldungen zu existieren, nicht einmal die verwendete Technologie zum Programmieren scheint irgendwie relevant.

Dazu muss man eben auch betrachten, dass jedes Ausprobieren locker eine Viertelstunde des Lebens kostet, denn das ist die Zeit, die es braucht, um eine neue Version so weit zu bringen, bis sie dann knallt oder auch nicht. Das ist in höchstem Maße frustrierend, auf sehr vielen verschiedenen Ebenen. Und ja, es gab noch mehr dieser Meldungen gestern, einschließlich einer Abweisung durch den AppStore, die ebenso unplausibel war, wie der Rest des Abends, denn bei identischer Wiederholung klappte es.

Die Freizeit

Ich werde nicht müde zu betonen, dass der GC Wizard ein reines Hobby ist, ein Freizeitprojekt. Und Freizeitprojekte sollten Spaß machen, der Entspannung dienen. Aktuell macht mir aber insbesondere dieser Teil ausschließlich Frust. Es ist kein Spaß daran, derart seine Zeit zu verbringen. Man kann es nicht einmal unter Lernen und Weiterbildung abstempeln, denn, wie beschrieben, ein Erkenntnisgewinn entsteht nicht.

Ich hatte damals die iOS-Version erstellt, weil ich die gesamte Geocacher-Community versorgen wollte. Deswegen wählte ich damals die Flutter-Technologie, weil diese versprach, dass man ohne großen Mehraufwand mehrere Plattformen versorgen kann. Und das klappte lange sehr gut – und tut es im Grunde ja immernoch. Doch hier haben wir es scheinbar mit Fehlern zu tun, die davon völlig unbenommen sind und eben auftreten oder auch nicht, egal was oder wie man es tut. Fakt ist, die iPhone-Version kostet momentan besonders viel Zeit und noch mehr Nerven. Es ist für uns ein ungeliebter Klotz am Bein, der immer größer und schwerer wird und ausschließlich an mir hängt. Denn in meinem Team will keiner diese Aufgabe von mir übernehmen, verständlicher Weise. Keiner von uns fühlt sich wohl in der Apple-Welt und Fälle wie die hier beschriebenen führen auch nicht dazu, dass jemand Lust bekommt, sich da einzuarbeiten. Wir müssen uns irgendwann klar die Frage stellen, ob wir weiter gewillt sind, unsere Freizeit auf derartige, fast ausschließlich negative Emotionen zu verwenden und die iPhone-Version weiter betreiben wollen.

Ich glaube, wenn wir einen dedizierten iPhone-Entwickler im Team hätten, würde das besser sein, auch weil er oder sie vermutlich direkt entsprechendes Arbeitsmaterial mitbringen würde. Tatsächlich habe ich persönlich die Theorie, dass sich wohl kaum OpenSource-Entwickler in der Community finden dürften, alle Projekte, die ich in die Richtung kenne, sind Android-Projekte. Im Gegenzug dazu sind alle Geocaching-Projekte für iOS, Cachly und Looking4Cache, Closed Source und kostenpflichtig (bzw. im Fall von L4C, was zwar inzwischen wohl kostenlos ist, aber nur, weil es nicht mehr weiterentwickelt wird). Das scheint die Welt von Apple zu sein: Wenn es kein Geld einbringt, macht es niemand. Und umgekehrt kenne ich nur Leute, die in die Apple-Welt einsteigen, weil ja alles so schön einfach ist. Vielleicht entstehen aus so einer (scheinbaren!) Perfektion aber wiederum gar keine Anreize, sich etwas Eigenes aufzubauen – irgendjemand wird mir da schon etwas hinstellen. Lustiger Weise ist es aber mitnichten so, dass die Leute gern etwas bezahlen, wenn sie nicht müssen. Denn die Gold-Version hat nur marginal mehr Verkäufe als bei Android: Auf beiden Plattformen sind wir deutlich bei unter einem Prozent der Nutzer.

Ich möchte euch nicht in einer so seltsamen Stimmung nach Hause schicken, vor allem weil ihr scheinbar überhaupt so lange mitgelesen habt. Generell möchte ich einfach auch mal sagen, dass ich die aktuelle Version einfach mal richtig großartig finde. Dass mein Team und ich es geschafft haben, über die letzten vier Jahre eine unfassbar mächtige und hochprofessionelle Software für alle Geocacher gratis und quelloffen zur Verfügung zu stellen. Ein Tool, was eigentlich kein Herz mehr offen lassen dürfte. Ich bin wirklich wirklich ein stolzer Daddy, der sein Baby sehr oft einfach nur öffnet und einfach sanft durch seine vielen Tools streicht. Es freut mich einfach jedes Mal aufs neue, dass wir das allen Widrigkeiten zum Trotz bis hierhin gebracht haben. Wer hätte das vor vier Jahren gedacht?