Das Problem mit Swift Macros in CI-Umgebungen
Swift Macros, eingeführt in Xcode 15 mit Swift 5.9, sind ein mächtiges Feature, das Code-Generierung und Metaprogrammierung zur Compile-Zeit ermöglicht. Während sie hervorragende Produktivitätsvorteile bieten, haben sie eine neue Herausforderung für CI/CD-Pipelines geschaffen – insbesondere in Xcode Cloud.
Wenn du ein Macro zum ersten Mal lokal verwendest, zeigt Xcode einen Dialog an, der dich auffordert, dem Package des Macros zu vertrauen, bevor es ausgeführt werden kann. Das funktioniert auf deinem Entwicklungsrechner problemlos, wird aber in automatisierten Umgebungen wie Xcode Cloud zum Problem, wo es eben keine Möglichkeit gibt, auf “OK” in einem Dialogfenster zu klicken.
Wenn du schon mal versucht hast, ein Projekt mit Swift Macros in Xcode Cloud zu bauen, bist du wahrscheinlich auf diesen frustrierenden Fehler gestoßen:
Target must be enabled before it can be used.Die vollständige Lösung
Nach einiger Recherche habe ich eine zuverlässige Lösung gefunden, die bei Xcode Cloud Builds mit Swift Macros konsistent funktioniert. So implementierst du sie:
Schritt 1: Einen CI-Scripts-Ordner erstellen
Erstelle zunächst einen eigenen Ordner für unsere CI-Skripte:
Rechtsklick auf dein Projekt in Xcode
Wähle “New Group”
Benenne ihn
ci_scripts
Schritt 2: Das Post-Clone-Skript erstellen
Als Nächstes erstellen wir ein Post-Clone-Skript, das Xcode Cloud automatisch nach dem Klonen deines Repositories ausführt:
Rechtsklick auf den Ordner
ci_scriptsWähle “New File” -> “Empty File”
Benenne es
ci_post_clone.sh
Schritt 3: Den Skriptinhalt hinzufügen
Kopiere den folgenden Code in deine neue Datei ci_post_clone.sh:
#!/bin/sh
# Bei Fehler abbrechen (-e), undefinierte Variablen (-u) und Pipeline-Fehler (-o pipefail)
set -euo pipefail
# Xcode-Macro-Fingerprint-Validierung deaktivieren, um fehlerhafte Build-Fehler zu vermeiden
defaults write com.apple.dt.Xcode IDESkipMacroFingerprintValidation -bool YESDieses Skript tut eine entscheidende Sache: Es deaktiviert Xcodes Macro-Fingerprint-Validierung – also genau das, was den Vertrauensdialog überhaupt auslöst.
Schritt 4: Das Skript ausführbar machen
Öffne das Terminal, navigiere zu deinem Projektordner und führe aus:
chmod +x ci_scripts/ci_post_clone.shDieser Befehl macht dein Skript ausführbar, was erforderlich ist, damit Xcode Cloud es korrekt ausführen kann.
Schritt 5: Committen und einen Build auslösen
Committe die neue Datei in dein Repository und pushe die Änderungen. Das löst einen neuen Build in Xcode Cloud aus, der jetzt ohne den Macro-Vertrauensfehler erfolgreich durchlaufen sollte.
So sieht es aus
Wenn alles korrekt eingerichtet ist, sollte deine Projektstruktur den CI-Scripts-Ordner mit dem Post-Clone-Skript enthalten:

Warum das funktioniert
Xcode Cloud führt automatisch jedes Skript mit dem Namen ci_post_clone.sh aus, das sich in einem ci_scripts-Verzeichnis im Root deines Projekts befindet. Unser Skript ändert die Xcode-Einstellungen, um die Macro-Fingerprint-Validierung zu deaktivieren und so die Vertrauensanforderung zu umgehen.
Der Befehl defaults write com.apple.dt.Xcode IDESkipMacroFingerprintValidation -bool YES ändert eine spezifische Xcode-Einstellung, die steuert, ob Macros explizit vertraut werden muss, bevor sie verwendet werden können.
Sicherheitsaspekte
Manche Entwickler schlagen vor, die Datei macros.json (die vertrauenswürdige Macro-Fingerprints enthält) von deinem lokalen Rechner in die CI-Umgebung zu kopieren. Ich bin allerdings der Meinung, dass dieser Ansatz nicht unbedingt sicherer ist als die Validierung einfach zu deaktivieren.
Der entscheidende Punkt ist hier der Kontext: Xcode Cloud läuft in einer Sandbox-Umgebung, die speziell zum Bauen deiner Anwendung dient. Es führt keinen beliebigen Code auf Produktionssystemen aus. Wenn du deinem Entwicklungsteam und deinem Release-Workflow nicht vertrauen kannst, hast du wahrscheinlich schwerwiegendere Sicherheitsprobleme als Macros, die in einer CI-Umgebung laufen.
Die wachsende Bedeutung dieser Lösung
Da Swift sich stetig weiterentwickelt, implementieren immer mehr Third-Party-Packages Macros, um leistungsstarke Features mit minimalem Boilerplate zu bieten. Zum Beispiel:
TranslateKit SDK bietet Lokalisierungs-Macros
Verschiedene Logging- und Debugging-Bibliotheken setzen auf Macros
UI-Frameworks nutzen Macros, um View-Deklarationen zu vereinfachen
Dieser Trend wird sich nur beschleunigen, da Entwickler immer neue Einsatzmöglichkeiten für Compile-Zeit-Metaprogrammierung entdecken. Eine zuverlässige Lösung für den Umgang mit Macros in CI-Pipelines wird für Swift-Projekte zunehmend wichtig.
Jetzt, da du das Macro-Vertrauensproblem gelöst hast, kannst du die Möglichkeiten von Xcode Cloud voll ausschöpfen. Ich werde in meinem nächsten Artikel und dem dazugehörigen Video zeigen, wie man Xcode Cloud für App-Store-Deployments nutzt. Dieser Ansatz kann dir wertvolle Zeit beim Warten auf Builds sparen, besonders wenn du wie ich auf mehreren Apple-Plattformen (iOS, macOS, visionOS) veröffentlichst. Bleib dran und viel Spaß beim Coden!

