.xcconfig ist eine Xcode-Konfigurationsdatei im Format „Schlüssel=Wert“, die die Build-Einstellungen eines Projekts zentral verwaltet. Anstatt die Parameter für jede Konfiguration manuell in der Xcode-Oberfläche zu ändern, beschreiben Entwickler sie in einer Textdatei, die versioniert und zwischen Projekten wiederverwendet werden kann. Laut Apple Developer Documentation, 2025 reduziert die Verwendung von .xcconfig die Projekteinrichtungszeit um 70% und beseitigt Konfigurationsunterschiede zwischen Entwicklern. .xcconfig-Dateien können voneinander erben und bilden so eine Konfigurationskette.
Wichtige Punkte
.xcconfig (Xcode-Konfigurationsdatei) ist eine reine Textdatei, die Build-Einstellungen im Format PARAMETER_NAME = value enthält. .xcconfig-Dateien werden zur zentralen Verwaltung von Xcode-Build-Konfigurationen verwendet: Sie ersetzen die manuelle Bearbeitung von Feldern in der Build-Einstellungen-Oberfläche. Jede .xcconfig ist mit einer Build-Konfiguration (Debug, Release) oder dem gesamten Projekt verknüpft und kann jede Build-Einstellung überschreiben: SWIFT_VERSION, IPHONEOS_DEPLOYMENT_TARGET, PRODUCT_BUNDLE_IDENTIFIER, CODE_SIGN_STYLE, PROVISIONING_PROFILE_SPECIFIER.
Vor dem Aufkommen von .xcconfig wurden Build-Einstellungen nur in project.pbxproj gespeichert — einer binären/plist-Datei, die in Diffs schwer zu lesen und nicht zu kommentieren ist. .xcconfig löste dieses Problem: Entwickler können Parameter kommentieren, nach Bedeutung gruppieren, versionierbare Dateien für verschiedene Umgebungen erstellen und Parameter zwischen Dateien vererben. Dies machte .xcconfig zum De-facto-Standard für die Konfigurationsverwaltung in iOS-Projekten.
.xcconfig-Dateien befinden sich innerhalb des Projekts, normalerweise im Ordner Configurations/ oder BuildConfig/. Jede Datei entspricht einer Build-Konfiguration: Debug.xcconfig, Release.xcconfig, Staging.xcconfig. Zusätzlich wird eine gemeinsame Shared.xcconfig-Datei erstellt, die über #include in alle Konfigurationen eingebunden wird. Dies ermöglicht es, gemeinsame Parameter einmal zu definieren und spezifische in den Konfigurationsdateien zu überschreiben.
Diff-Lesbarkeit: Änderungen in .xcconfig sind im Git-Diff als normale Zeilen sichtbar. Anders als bei project.pbxproj, wo eine Änderung der Feldreihenfolge 50 Änderungszeilen für eine einzelne Parameterbearbeitung anzeigt. Kommentare: In .xcconfig kann erklärt werden, warum jeder Parameter benötigt wird. Vererbung: Eine Basiskonfiguration mit gemeinsamen Einstellungen kann erstellt werden, und nur die für Debug und Release benötigten Parameter werden überschrieben.
Die Syntax von .xcconfig ist so einfach wie möglich: Jede Zeile ist ein Parameter, Name und Wert durch ein Gleichheitszeichen getrennt. Leerzeichen um = werden ignoriert. Werte können Variablen im Format $(VARIABLE_NAME) oder ${VARIABLE_NAME} enthalten. Kommentare beginnen mit // oder # und gelten bis zum Zeilenende. Zeilen werden mit einem Backslash \ in der nächsten Zeile fortgesetzt. Leere Zeilen werden ignoriert.
Variablen in .xcconfig können auf andere Variablen verweisen und so zusammengesetzte Werte erstellen. Zum Beispiel: PRODUCT_NAME = MyApp, PRODUCT_BUNDLE_IDENTIFIER = com.example.$(PRODUCT_NAME). Xcode wertet den Wert zur Build-Zeit aus, indem es die tatsächlichen Variablenwerte einsetzt. AGP unterstützt auch Systemvariablen: ARCHS, SDK_NAME, CONFIGURATION, PLATFORM_NAME, die von der Build-Umgebung festgelegt werden.
Für bedingte Konfiguration werden Plattformdirektiven in eckigen Klammern verwendet: PARAMETER[sdk=iphoneos*] = value. Zum Beispiel setzt SUPPORTED_PLATFORMS[sdk=iphoneos*] = iphoneos den Parameter nur für iOS-Builds. Platzhalter werden unterstützt: * (beliebige Zeichen), ? (ein Zeichen). Bedingte Direktiven ermöglichen es, eine .xcconfig für mehrere Plattformen zu haben und in einer Datei unterschiedliche Werte für iOS und macOS festzulegen.
// Shared.xcconfig — gemeinsame Projekteinstellungen
SWIFT_VERSION = 5.0
IPHONEOS_DEPLOYMENT_TARGET = 16.0
SDKROOT = iphoneos
TARGETED_DEVICE_FAMILY = 1,2
// Bundle-ID — wird aus Präfix und Name zusammengesetzt
BUNDLE_ID_PREFIX = com.example
PRODUCT_NAME = MyApp
PRODUCT_BUNDLE_IDENTIFIER = $(BUNDLE_ID_PREFIX).$(PRODUCT_NAME)
// Bedingte Einstellung für macOS
SUPPORTED_PLATFORMS[sdk=macosx*] = macosx
PRODUCT_BUNDLE_IDENTIFIER[sdk=macosx*] = $(BUNDLE_ID_PREFIX).$(PRODUCT_NAME).mac
// Versionierung
MARKETING_VERSION = 2.4.1
CURRENT_PROJECT_VERSION = 37
#include ist eine .xcconfig-Präprozessordirektive, die den Inhalt einer anderen .xcconfig-Datei einbindet. Direktiven können verschachtelt werden: Shared.xcconfig kann „Base.xcconfig“ #include, Debug.xcconfig kann „Shared.xcconfig“ #include. Die Vererbungskette ermöglicht den Aufbau einer Konfigurationshierarchie, bei der jede Ebene die Parameter der vorherigen überschreibt. #include funktioniert nach dem Prinzip der letzten Schreibweise: Wenn derselbe Parameter sowohl in der eingebundenen als auch in der Hauptdatei definiert ist, hat der Wert aus der Hauptdatei Priorität.
Die richtige Hierarchie für ein typisches iOS-Projekt: Base.xcconfig (allgemeinste Parameter) → Shared.xcconfig (Projekteinstellungen) → Debug.xcconfig oder Release.xcconfig. Base.xcconfig definiert Standards (SWIFT_VERSION, DEPLOYMENT_TARGET), Shared.xcconfig — Projektspezifika (PRODUCT_NAME, PREPROCESSOR_DEFINITIONS), Debug/Release — Umgebung (DEBUG_INFORMATION_FORMAT, OPTIMIZATION_CFLAGS). #include erlaubt keine Zyklen — Xcode gibt einen Fehler aus, wenn eine zyklische Abhängigkeit erkannt wird.
Beispiel: Config/Base.xcconfig → Config/iOS/Shared.xcconfig → Config/iOS/Debug.xcconfig. Diese Struktur ermöglicht die Wiederverwendung von Base für iOS-, macOS- und tvOS-Projekte und Shared nur für iOS. Hinweis: #include verwendet einen Dateinamen oder relativen Pfad vom Speicherort der Stamm-.xcconfig. Absolute Pfade werden nicht empfohlen — sie brechen den Build auf anderen Maschinen und in CI/CD.
// --- Config/Base.xcconfig ---
SWIFT_VERSION = 5.0
ENABLE_MODULE_VERIFIER = YES
CLANG_ENABLE_MODULES = YES
// --- Config/iOS/Shared.xcconfig ---
#include "../Base.xcconfig"
IPHONEOS_DEPLOYMENT_TARGET = 16.0
PRODUCT_BUNDLE_IDENTIFIER = com.example.myapp
// --- Config/iOS/Debug.xcconfig ---
#include "Shared.xcconfig"
OPTIMIZATION_CFLAGS = -O0
DEBUG_INFORMATION_FORMAT = dwarf
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG
ENABLE_TESTABILITY = YES
// --- Config/iOS/Release.xcconfig ---
#include "Shared.xcconfig"
OPTIMIZATION_CFLAGS = -Osize
DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
SWIFT_COMPILATION_MODE = wholemodule
Das Einbinden von .xcconfig in ein Projekt erfolgt unter Project Info → Configurations. Für jede Build-Konfiguration (Debug, Release, AdHoc) wird die entsprechende .xcconfig aus dem Dropdown-Menü „Based on Configuration File“ ausgewählt. Wenn eine Konfiguration nicht mit einer Datei verknüpft ist, verwendet Xcode die Werte aus project.pbxproj. Nach Auswahl der .xcconfig werden alle Parameter aus der Datei für diese Konfiguration aktiv.
Es ist wichtig, zwischen Konfigurationen auf Projekt- und Target-Ebene zu unterscheiden. Eine .xcconfig auf Projektebene legt Standardparameter für alle Targets fest. Eine .xcconfig auf Target-Ebene überschreibt sie für ein bestimmtes Target. Wenn ein Parameter in der .xcconfig auf Target-Ebene nicht festgelegt ist, wird der Wert von der Projektebene verwendet. Ist er auch dort nicht festgelegt, wird der Wert aus project.pbxproj verwendet. Faustregel: Gemeinsame Parameter (Build, Versionen) auf Projektebene, Targetspezifika (Bundle-ID, Provisioning) auf Target-Ebene.
Bei einem Konflikt zwischen .xcconfig und UI-Build-Einstellungen hat der Wert aus der UI Priorität (er überschreibt .xcconfig). Dies kann zu Verwirrung führen: Ein Entwickler ändert eine Build-Einstellung in der UI, ohne zu wissen, dass .xcconfig einen anderen Wert vorgibt. Es wird empfohlen, vollständig auf .xcconfig umzusteigen und die UI-Build-Einstellungen nicht zu berühren. Um zu überprüfen, welcher Parameter angewendet wird, verwenden Sie xcrun xcodebuild -showBuildSettings — der Befehl zeigt die endgültigen Werte aller Parameter nach Auflösung aller Ebenen an.
Betrachten Sie eine dreistufige Konfiguration: Dev (lokale Entwicklung), Staging (Testserver), Production (Release). Für jede Umgebung wird eine separate .xcconfig erstellt, die unterschiedliche API_URL-, Logging- und Zertifikatswerte definiert. Dev verwendet localhost, Staging verwendet staging.api.example.com, Production verwendet api.example.com. Alle drei erben die gemeinsame Shared.xcconfig über #include.
Der wichtigste Parameter, der sich zwischen den Umgebungen unterscheidet, ist PRODUCT_BUNDLE_IDENTIFIER. Für Dev: com.example.myapp.dev, für Staging: com.example.myapp.staging, für Production: com.example.myapp. Unterschiedliche Bundle-IDs ermöglichen die gleichzeitige Installation aller drei Versionen auf einem Gerät. Ebenfalls unterschiedlich sind CODE_SIGN_IDENTITY (Apple Development für Dev, Apple Distribution für Production) und PROVISIONING_PROFILE_SPECIFIER.
Zum Übergeben von Werten an den Code werden INFOPLIST_PREFIX_HEADER oder OTHER_SWIFT_FLAGS mit -D-Präprozessor verwendet. Swift hat keinen Präprozessor, daher werden Active Compilation Conditions verwendet: SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEV. Im Code: #if DEV; #elseif STAGING; #else; #endif. Für Objective-C wird GCC_PREPROCESSOR_DEFINITIONS verwendet. Dies ermöglicht das Kompilieren unterschiedlichen Codes für verschiedene Umgebungen ohne Änderung der Quelldateien.
// --- Config/Dev.xcconfig ---
#include "Shared.xcconfig"
PRODUCT_BUNDLE_IDENTIFIER = $(BUNDLE_ID_PREFIX).$(PRODUCT_NAME).dev
CODE_SIGN_IDENTITY = Apple Development
PROVISIONING_PROFILE_SPECIFIER = Dev Profile
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG DEV
OTHER_SWIFT_FLAGS = -D DEV
// API-Über über Info.plist — Wert wird ersetzt
API_BASE_URL = http://localhost:3000/api
// --- Config/Staging.xcconfig ---
#include "Shared.xcconfig"
PRODUCT_BUNDLE_IDENTIFIER = $(BUNDLE_ID_PREFIX).$(PRODUCT_NAME).staging
CODE_SIGN_IDENTITY = Apple Development
PROVISIONING_PROFILE_SPECIFIER = Staging Profile
SWIFT_ACTIVE_COMPILATION_CONDITIONS = STAGING
OTHER_SWIFT_FLAGS = -D STAGING
API_BASE_URL = https://staging.api.example.com/v2
// --- Config/Production.xcconfig ---
#include "Shared.xcconfig"
PRODUCT_BUNDLE_IDENTIFIER = $(BUNDLE_ID_PREFIX).$(PRODUCT_NAME)
CODE_SIGN_IDENTITY = Apple Distribution
PROVISIONING_PROFILE_SPECIFIER = AppStore Distribution
SWIFT_ACTIVE_COMPILATION_CONDITIONS = RELEASE
API_BASE_URL = https://api.example.com/v3
Werte aus .xcconfig können über Variablen $(PARAMETER_NAME) an Info.plist übergeben werden. Wenn ein Parameter in .xcconfig definiert ist (z. B. API_BASE_URL), kann er in Info.plist verwendet werden: <key>ApiBaseUrl</key><string>$(API_BASE_URL)</string>. Zur Build-Zeit ersetzt Xcode $(API_BASE_URL) durch den Wert aus .xcconfig. Dies ermöglicht die Konfiguration der Anwendung ohne Codeänderung — einfach das Schema wechseln.
In Info.plist verwendete .xcconfig-Parameter müssen öffentlich sein — sie gelangen in die Binärdatei und sind in der dekompilierten Anwendung sichtbar. Verwenden Sie .xcconfig nicht für geheime Werte (Tokens, Passwörter) — verwenden Sie Dienste wie Firebase Remote Config, die auf dem Server ausgeführt werden. .xcconfig für Info.plist ist geeignet für: Server-URLs, Entitätsnamen, Tracker-Kennungen, Feature-Flags.
Zugriff auf Info.plist-Werte im Code: Bundle.main.object(forInfoDictionaryKey: „ApiBaseUrl“) für Objective-C/Swift. Wenn der Wert über .xcconfig festgelegt wurde, wird er ersetzt und ist in Bundle main.infoDictionary verfügbar. Diese Methode ist BuildConfigField (wie in Android) vorzuziehen, da Info.plist ein Standard-iOS-Mechanismus ist und seine Werte allen Systemkomponenten einschließlich Erweiterungen, Widgets und Siri Intents zur Verfügung stehen.
Häufig gestellte Fragen
User-Defined Setting ist ein benutzerdefinierter Parameter, der über die UI-Build-Einstellungen hinzugefügt wurde. Es funktioniert genauso wie .xcconfig, kann aber nicht versioniert, kommentiert oder zwischen Projekten wiederverwendet werden. .xcconfig ist eine Datei auf der Festplatte, User-Defined Setting ein Eintrag in project.pbxproj.
Ja, CocoaPods generiert Pods-*.xcconfig-Dateien für jede Konfiguration. Diese Dateien enthalten Einstellungen zum Anschließen der Pods. Pods.xcconfig wird automatisch über #include in der Generator-Datei mit Ihrer .xcconfig verknüpft. Bearbeiten Sie Pods.xcconfig nicht manuell — es wird bei pod install überschrieben.
Über Info.plist: Definieren Sie einen Parameter in .xcconfig und verwenden Sie $(PARAM) in Info.plist. Im Code: Bundle.main.infoDictionary[„PARAM“]. Für Präprozessor-Flags verwenden Sie SWIFT_ACTIVE_COMPILATION_CONDITIONS und #if CONDITION.
Gründe: Sie haben den Wert in den UI-Build-Einstellungen geändert (UI überschreibt .xcconfig); die Datei ist nicht mit der Konfiguration verknüpft (prüfen Sie Project → Info → Configurations); falscher #include-Pfad; Tippfehler im Parameternamen. Diagnose: xcodebuild -showBuildSettings zeigt alle aktiven Parameter an.
Ja, .xcconfig ist unabhängig vom UI-Framework. Für SwiftUI-Projekte ist .xcconfig gleichermaßen nützlich: Verwaltung von Bundle-ID, Versionen, Umgebungskonfigurationen, SWIFT_ACTIVE_COMPILATION_CONDITIONS für Feature-Flags. SwiftUI bietet keine Alternative zu .xcconfig, daher wird die Verwendung mit jedem Projekt empfohlen.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch