Wer ein Audit beauftragt, erwartet meistens ein Urteil über den Code. Ich sehe mir den Code zuletzt an. Nicht aus Koketterie, sondern weil er die am wenigsten belastbare Auskunft über das Risiko gibt: Ich kann eine hässliche Datei in einer Stunde lesen und danach immer noch nicht wissen, ob dieses Team nächsten Monat ein Update ausliefern kann.
Deshalb beginnt jedes Audit mit einer Frage, die nichts mit Ästhetik zu tun hat: Was kostet die nächste Änderung — und was steht ihr im Weg?
Warum die Reihenfolge das Ergebnis bestimmt
Zehn Arbeitstage sind knapp für eine fremde Codebasis. Man kann sie vollständig lesen wollen und scheitern, oder man kann sie in einer Reihenfolge prüfen, in der jeder Schritt den nächsten verkleinert. Ich mache das zweite.
Die Reihenfolge folgt einem Prinzip: zuerst das, was den Weiterbau blockiert, dann das, was ihn verlangsamt, zuletzt das, was ihn unangenehm macht. Ein Projekt, das sich nicht bauen lässt, hat kein Architekturproblem — es hat ein Bauproblem, und jede Aussage über die Architektur wäre bis dahin Spekulation.
Das ist auch der Grund, warum ich Befunde nicht nach Schwere des Verstoßes sortiere, sondern nach Kosten der nächsten Änderung. Beides fällt seltener zusammen, als man denkt.
Zuerst: baut es, und zwar auf einem fremden Rechner
Der erste Test ist die Übernahme selbst. Repository klonen, Abhängigkeiten auflösen, bauen, auf einem Gerät starten — ohne Zuruf von jemandem, der das Projekt kennt.
Was dabei schiefgeht, ist der eigentliche Befund. Fehlende Konfigurationsdateien, die nie eingecheckt wurden. Ein Schritt, den jeder im Team kennt und niemand aufgeschrieben hat. Signierung, die an einem persönlichen Konto hängt. Jede dieser Hürden kostet einen neuen Entwickler Tage, und sie kostet ihn diese Tage jedes Mal wieder.
Ich messe dabei nur zwei Dinge: wie lange es dauert, bis ich einen laufenden Build habe, und wie oft ich fragen musste. Beides landet im Bericht, weil beides direkt die Einarbeitungszeit jedes künftigen Entwicklers vorhersagt.
Dann: die Abhängigkeiten und ihr Verfallsdatum
Danach sehe ich mir an, woraus die App außer eigenem Code noch besteht. Die Anzahl der Bibliotheken sagt wenig. Ihr Zustand sagt alles: Welche werden noch gepflegt, welche sind seit Jahren unberührt, welche hängen an einer Plattformversion, die Apple bald nicht mehr akzeptiert.
Der kritische Fall ist eine nicht mehr gepflegte Bibliothek an einer zentralen Stelle — Netzwerk, Datenbank, Authentifizierung. Sie funktioniert heute tadellos und ist trotzdem ein terminierter Posten: Beim nächsten erzwungenen SDK-Wechsel wird sie zum Blocker, und der Austausch trifft dann alles, was sie berührt.
Ebenso wichtig ist die Gegenrichtung: eigener Code, der so eng an einer solchen Bibliothek klebt, dass ein Austausch die halbe App aufreißt. Das ist der Befund, der später im Katalog die höchste Aufwandszahl trägt, obwohl im Code nichts kaputt aussieht.
Dann: Tests, aber als Auskunft über das Team
Testabdeckung als Prozentzahl sagt fast nichts. Interessant ist, was getestet ist. Liegen die Tests dort, wo das Geld verdient wird — Bezahlung, Anmeldung, Datensynchronisation — oder dort, wo sie leicht zu schreiben waren?
Zwei Fragen beantworten das schneller als jede Metrik. Laufen die Tests in der CI wirklich, oder sind sie irgendwann abgeschaltet worden? Und: Wann wurde der letzte Test geschrieben? Eine Suite, die vor zwei Jahren stehengeblieben ist, ist kein Sicherheitsnetz, sondern ein Fundstück.
Was ich hier lese, ist weniger ein technischer Zustand als eine Auskunft darüber, unter welchem Druck dieses Team zuletzt gearbeitet hat.
Dann: der Weg vom Commit in den Store
Jetzt wird die Frage konkret: Wie kommt eine fertige Änderung zum Nutzer, und wer kann diesen Weg gehen? Ich sehe mir an, ob es überhaupt eine automatisierte Pipeline gibt, wie lange ein Release dauert, wie viele Handgriffe manuell sind und wie viele Personen das ausführen können.
Die Antwort auf die letzte Frage lautet erstaunlich oft: eine. Genau das ist ein Architekturbefund, auch wenn er in keiner Klasse steht. Ein Release-Weg, den nur ein Mensch beherrschen kann, ist dasselbe Risiko wie ein Zugang, der auf einen Namen läuft.
Wie oft in den letzten Monaten tatsächlich released wurde, sagt außerdem mehr über die Änderbarkeit der App als jedes Diagramm. Wo lange nichts ausgeliefert wurde, ist meistens nicht die Nachfrage eingeschlafen, sondern der Weg zu unangenehm geworden.
Und erst dann: der Code
Wenn ich beim Code ankomme, weiß ich bereits, wo ich hinsehen muss. Gelesen werden die Stellen, die die vorherigen Schritte markiert haben: was jede Änderung anfasst, was an der veralteten Bibliothek hängt, was ungetestet und gleichzeitig geschäftskritisch ist.
Dort schaue ich auf Änderbarkeit, nicht auf Schönheit. Wie viele Dateien muss ich anfassen, um ein Feld hinzuzufügen? Gibt es eine erkennbare Schichtung, oder kennt jede Stelle jede andere? Wie groß sind die Klassen, die alle anderen benutzen?
Hässlicher Code, der zuverlässig baut, testbar ist und regelmäßig released wird, ist ein handhabbares Problem. Eleganter Code, den niemand ausliefern kann, ist keins.
Wofür diese Reihenfolge nicht taugt
Diese Reihenfolge liefert kein Qualitätsurteil, und manche Auftraggeber vermissen es. Wer eine Note für seine Codebasis erwartet oder die Bestätigung, dass der Vorgänger schlecht gearbeitet hat, bekommt sie von mir nicht. Der Katalog sagt, was die nächste Änderung teuer macht — nicht, wer schuld ist.
Der zweite Preis ist echte Unschärfe: In zehn Tagen lese ich nicht die ganze Codebasis. Ich prüfe stichprobenartig entlang der Risiken, die die ersten Schritte aufgedeckt haben. Ein Fehler, der außerhalb dieser Spuren liegt, kann mir entgehen. Das steht so auch im Bericht, weil eine Vollständigkeitsbehauptung nach zehn Tagen unseriös wäre.
Wo das nicht funktioniert
Die Reihenfolge setzt voraus, dass es einen Weiterbau gibt, dessen Kosten sich messen lassen. Steht die Grundsatzfrage anders — verkaufen, einstellen, komplett neu bauen — verschiebt sich der Fokus, und Fragen nach Datenmigration und Betriebsrisiko werden wichtiger als Änderbarkeit.
Sie funktioniert außerdem schlecht bei sehr kleinen Apps. Wo insgesamt wenige tausend Zeilen liegen, ist ein strukturiertes Audit Overhead: Dann liest man den Code einfach, und das dauert zwei Tage statt zehn.
Und sie ersetzt kein Sicherheitsaudit. Ich prüfe Grundlagen — wie mit Zugangsdaten, Schlüsseln und Nutzerdaten umgegangen wird. Ein Penetrationstest ist etwas anderes und gehört in andere Hände.
Was am Ende dasteht
Nach zehn Tagen liegt ein priorisierter Maßnahmenkatalog vor: jeder Befund mit Risiko, geschätztem Aufwand und einer empfohlenen Reihenfolge. Kein Gutachten fürs Regal, sondern eine Liste, die ein Team am Montag abarbeiten kann.
Die häufigste Reaktion im Abschlussgespräch ist übrigens nicht Überraschung. Es ist Erleichterung darüber, dass das, was alle geahnt haben, jetzt eine Zahl und eine Reihenfolge hat. Genau dafür ist das Dokument da: Es macht aus einem Bauchgefühl eine Entscheidungsgrundlage — auch für die Entscheidung, erst mal nichts zu tun.
Wie das als Paket geschnitten ist, steht auf der Seite zum iOS Architektur-Audit.