Scheme: istota, konfiguracja i uruchamianie w Xcode

Autor: IT Sectr Opublikowano: 2026-05-30 Czas czytania: 9 min

Scheme w Xcode to konfiguracja, która określa, jak budować, testować, profilować i archiwizować aplikację dla iOS, macOS, watchOS lub tvOS. Każda Scheme zawiera zestaw akcji (Build, Run, Test, Profile, Analyze, Archive) z własnymi parametrami, argumentami i zmiennymi środowiskowymi. Według Apple Developer Documentation, 2025 Scheme jest głównym narzędziem zarządzania konfiguracjami budowania w Xcode, zastępując ręczne przełączanie parametrów. Xcode automatycznie tworzy schemat dla każdego targetu przy pierwszym otwarciu projektu.

Najważniejsze

  • Scheme — konfiguracja Xcode z zestawem akcji do budowania, testowania i archiwizowania.
  • Build — kompilacja targetów z zadaną konfiguracją (Debug lub Release).
  • Run — uruchamianie aplikacji z argumentami, zmiennymi środowiskowymi i punktem wejścia.
  • Test — uruchamianie testów unit i UI z wyborem zestawu testów.
  • Archive — budowanie do publikacji w App Store z konfiguracją produkcyjną.

Czym jest Scheme w Xcode?

Scheme w Xcode to plik XML (rozszerzenie .xcscheme), który opisuje sekwencję akcji i ich parametry do budowania i analizy aplikacji. Każda Scheme jest powiązana z jednym lub kilkoma targetami i określa, z jaką konfiguracją (Debug, Release, AdHoc) wykonać każdą akcję. Scheme to odpowiednik Build Variant w Androidzie, ale o bardziej elastycznej strukturze: jeden schemat może zawierać różne targety dla różnych akcji.

Xcode automatycznie tworzy schemat dla każdego targetu przy pierwszym otwarciu projektu. Nazwa schematu domyślnie pokrywa się z nazwą targetu. Jeśli w projekcie jest target testowy, Xcode automatycznie dodaje go do akcji Test schematu głównego targetu. Dla projektów z wieloma targetami (główna aplikacja + watchOS + extension) Xcode tworzy osobny schemat dla każdego, ale można utworzyć jeden schemat, który buduje wszystkie targety naraz.

Schematy są przechowywane w katalogu xcshareddata/xcschemes/ (dla shared) lub xcuserdata/<user>/xcschemes/ (dla private). Schematy shared trafiają do Gita i są używane przez cały zespół. Schematy private są przechowywane lokalnie i nie są synchronizowane. Plik .xcscheme ma format XML z elementem głównym <Scheme>. Wewnątrz znajdują się bloki dla każdej akcji: BuildAction, TestAction, LaunchAction, ProfileAction, AnalyzeAction, ArchiveAction.

Struktura pliku .xcscheme

.xcscheme to plik XML, który można edytować ręcznie lub przez Xcode. Główne elementy: <BuildAction> (lista budowanych targetów), <TestAction> (odniesienia do targetów testowych), <LaunchAction> (konfiguracja uruchamiania), <ProfileAction>, <AnalyzeAction>, <ArchiveAction>. Każdy blok zawiera atrybut buildConfiguration, który określa, jaką konfigurację (Debug/Release) użyć dla danej akcji.

Akcje Scheme: Build, Run, Test, Profile, Analyze, Archive

Scheme składa się z sześciu akcji, z których każdą można skonfigurować niezależnie. Akcja Build określa, które targety są budowane i w jakiej kolejności. Akcja Run — jak uruchamiana jest aplikacja: z jakimi argumentami, zmiennymi środowiskowymi i z jaką konfiguracją. Akcja Test — które testy są wykonywane i jakie opcje code coverage są włączone. Akcja Profile — uruchamianie z narzędziami Instruments do profilowania. Akcja Analyze — statyczna analiza kodu za pomocą Clang Static Analyzer. Akcja Archive — budowanie do publikacji w App Store lub dystrybucji AdHoc.

Dla każdej akcji można ustawić osobną build configuration. Zwykle dla Run i Test używa się Debug, a dla Archive — Release. Build configuration określa zestaw flag kompilatora, optymalizacje i informacje debugowania. Xcode udostępnia dwie standardowe konfiguracje: Debug (bez optymalizacji, z symbolami debugowania) i Release (z optymalizacjami, bez informacji debugowania). Deweloper może dodawać własne konfiguracje przez projekt.xcconfig.

Akcja Archive jest szczególnie ważna — tworzy .xcarchive, który następnie jest eksportowany do .ipa dla App Store lub AdHoc. Akcja Archive domyślnie używa konfiguracji Release, ale można przełączyć na AdHoc lub Distribution. W akcji Archive dostępna jest również flaga revealArchiveInOrganizer — po zakończeniu archiwizacji Xcode otwiera Organiser do dalszych działań z archiwum.

xml
<!-- Przykład .xcscheme dla aplikacji iOS -->
<Scheme
  LastUpgradeVersion = "1500"
  version = "1.7">

  <BuildAction
    parallelizeBuildables = "YES"
    buildImplicitDependencies = "YES">
    <BuildActionEntries>
      <BuildActionEntry
        buildForTesting = "YES"
        buildForRunning = "YES"
        buildForProfiling = "YES"
        buildForArchiving = "YES"
        buildForAnalyzing = "YES">
        <BuildableReference
          BuildableIdentifier = "primary"
          BlueprintIdentifier = "ABCD1234"
          BuildableName = "MyApp.app"
          BlueprintName = "MyApp"
          ReferencedContainer = "container:MyApp.xcodeproj">
        </BuildableReference>
      </BuildActionEntry>
    </BuildActionEntries>
  </BuildAction>

  <LaunchAction
    buildConfiguration = "Debug"
    selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
    enableAddressSanitizer = "YES">
  </LaunchAction>
</Scheme>

Tworzenie i konfiguracja Scheme

Sanitaryzery diagnostyczne

Tworzenie nowego schematu odbywa się przez menu Xcode: Product → Scheme → New Scheme lub przyciskiem „+“ w panelu Scheme (obok przycisku Run). Podczas tworzenia wybierany jest target, dla którego tworzony jest schemat. Xcode automatycznie kopiuje ustawienia z istniejącego schematu, jeśli jest on wybrany jako „duplicate“. Nowe schematy domyślnie są zapisywane jako private — aby udostępnić je zespołowi, trzeba włączyć Shared w Manage Schemes.

Okno Edit Scheme (Product → Scheme → Edit Scheme) zawiera sześć zakładek odpowiadających liczbie akcji. Na każdej zakładce można zmienić build configuration, argumenty uruchomieniowe, zmienne środowiskowe i flagi diagnostyczne. Na zakładce Run dostępne są opcje: executable (który plik binarny uruchomić), wait for executable to be launched (do debugowania uruchamianych procesów), debugger (LLDB lub None), launch arguments, environment variables oraz opcje rozszerzone (Address Sanitizer, Thread Sanitizer, Main Thread Checker, Memory Management).

Do diagnostyki Address Sanitizer (ASan) — wykrywa wyjście poza granice tablicy, use-after-free i inne błędy pamięci w kodzie C/C++/ObjC. Thread Sanitizer (TSan) — wykrywa stany wyścigu (data races) w kodzie wielowątkowym. Undefined Behavior Sanitizer (UBSan) — wykrywa niezdefiniowane zachowanie, na przykład przepełnienie ze znakowego int. Te opcje są dostępne w Edit Scheme → Run → Diagnostics i działają tylko dla wersji Debug. Włączenie wszystkich sanitizerów może spowolnić uruchamianie 2-3 razy, dlatego zaleca się włączanie ich wybiórczo.

Klonowanie schematu dla różnych środowisk

Typową praktyką jest tworzenie osobnych schematów dla każdego środowiska: Dev, Staging, Production. Każdy schemat używa tych samych Build Configuration (Debug dla Dev, Release dla Production), ale różnych argumentów uruchomieniowych: -FIRAnalyticsDebugEnabled, -com.apple.CoreData.SQLDebug 1 dla Dev i ich braku dla Production. Argumenty uruchomieniowe są przekazywane do UserDefaults (ProcessInfo.processInfo.arguments) i dostępne do odczytu przy starcie aplikacji. Pozwala to przełączać URL serwera, poziom logowania i funkcje bez zmiany kodu.

Schematy Shared i Private: zarządzanie przez Git

Schematy Shared są przechowywane w <project>.xcworkspace/xcshareddata/xcschemes/ lub <project>.xcodeproj/xcshareddata/xcschemes/ i trafiają do repozytorium Git. Wszyscy deweloperzy zespołu widzą te schematy w Xcode. Schematy Shared to jedyny sposób rozpowszechniania schematów w zespole. Jeśli deweloper utworzył ważny schemat (na przykład „Staging Archive“), ale nie oznaczył go jako Shared, reszta zespołu go nie zobaczy, co prowadzi do zamieszania: każdy będzie tworzył własny schemat z własnymi ustawieniami.

Schematy Private są przechowywane w xcuserdata/<user>/xcschemes/ i nie trafiają do Gita. Są przydatne do konfiguracji osobistych: na przykład schemat z włączonymi wszystkimi sanitizerami dla konkretnego dewelopera. Schematy private nie powinny zawierać krytycznych ustawień, od których zależy budowanie projektu — jeśli deweloper odejdzie z projektu, jego schematy private znikną. Zalecenie: wszystkie schematy używane w CI/CD i przez co najmniej dwóch deweloperów powinny być Shared.

Zarządzanie schematami odbywa się przez Manage Schemes (Product → Scheme → Manage Schemes). W oknie są wyświetlane wszystkie schematy projektu, ich status (Shared/Private) oraz przyciski +/— do dodawania/usuwania. Pole wyboru Shared przełącza widoczność schematu dla zespołu. Przy konflikcie Git (zmiany w .xcscheme od dwóch deweloperów) trzeba ostrożnie rozwiązywać scalanie — pliki XML mogą zawierać różne identyfikatory targetów. Zaleca się dodawanie .xcscheme do plików blokowanych przy merge (git lfs lub .gitattributes).

Argumenty uruchomieniowe i zmienne środowiskowe

Arguments w Scheme to ciągi, które są przekazywane aplikacji przy uruchamianiu (ProcessInfo.processInfo.arguments) oraz zmienne środowiskowe (ProcessInfo.processInfo.environment). Argumenty służą do flag: -AppleLanguages (ru), -AppleLocale ru_RU do symulacji rosyjskiej lokalizacji lub -FIRDebugEnabled do włączenia debugowania Firebase. Zmienne środowiskowe są stosowane do konfiguracji: API_BASE_URL=http://localhost:3000, LOG_LEVEL=debug.

Do zarządzania funkcjami (feature flags) w różnych środowiskach używa się kombinacji Arguments + Build Configuration. W schemacie Dev ustawiany jest argument -FeatureFlagNewOnboarding YES, a w Production — -FeatureFlagNewOnboarding NO (lub argument nie występuje). W kodzie sprawdzenie: UserDefaults.standard.bool(forKey: "FeatureFlagNewOnboarding"). To podejście pozwala stopniowo włączać funkcje na staging bez zmiany kodu i bez commitowania wartości produkcyjnych.

Ważne: argumenty i zmienne środowiskowe Scheme nadpisują wartości z Info.plist. Jeśli w Info.plist podano API_URL, a w Scheme — API_URL=http://localhost dla Run Action, przy uruchomieniu z Xcode zostanie użyta wartość ze Scheme. Przy uruchomieniu z urządzenia (nie z Xcode) — wartość z Info.plist. To wygodne do lokalnego rozwoju, ale trzeba pamiętać, że zmienne Scheme nie trafiają do kompilacji — działają tylko przy uruchamianiu przez Xcode.

swift
import Foundation

struct AppEnvironment {
    var apiBaseURL: String {
        ProcessInfo.processInfo.environment["API_BASE_URL"]
            ?? Bundle.main.object(forInfoDictionaryKey: "API_BASE_URL") as? String
            ?? "https://api.production.com"
    }

    var isDebugMode: Bool {
        ProcessInfo.processInfo.arguments.contains("-DebugModeEnabled")
    }

    var isNewOnboardingEnabled: Bool {
        UserDefaults.standard.bool(forKey: "FeatureFlagNewOnboarding")
    }
}

// Używane przy starcie
let env = AppEnvironment()
NetworkConfig.shared.configure(baseURL: env.apiBaseURL)

Scheme w CI/CD: automatyzacja przez xcodebuild

W CI/CD (GitHub Actions, Jenkins, GitLab CI) Scheme jest używana jako główny argument polecenia xcodebuild. Przykład: xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Release -sdk iphoneos archive. Flaga -scheme wskazuje, której schematu użyć. xcodebuild czyta wszystkie ustawienia z pliku .xcscheme, w tym build configuration, targety i kolejność budowania. To gwarantuje, że CI/CD buduje aplikację z tymi samymi parametrami co lokalne IDE.

Dla CI/CD krytyczne są schematy Shared. Jeśli schemat nie jest Shared, xcodebuild nie znajdzie go w repozytorium, a budowanie zakończy się błędem „Scheme not found“. Zasada: przed konfiguracją CI/CD upewnij się, że wszystkie używane schematy są oznaczone jako Shared. Druga zasada: w CI/CD nie używaj domyślnego schematu (Xcode automatycznie wybiera pierwszy schemat) — zawsze podawaj nazwę schematu jawnie przez flagę -scheme.

Do równoległego budowania kilku schematów (na przykład aplikacja i rozszerzenie watchOS) można uruchamiać xcodebuild sekwencyjnie lub równolegle. Nowoczesne systemy CI pozwalają zrównoleglić budowanie różnych schematów przez macierz: jedna praca buduje aplikację iOS, druga — rozszerzenie watchOS. To skraca całkowity czas budowania z 15 do 8 minut przy dwóch równoległych agentach. Na końcu artefakty są łączone w jeden .xcarchive za pomocą xcodebuild -exportArchive.

bash
#!/bin/bash — CI/CD budowa z xcodebuild
# 1. Czyszczenie i budowanie
xcodebuild clean archive \
  -workspace "MyApp.xcworkspace" \
  -scheme "MyApp Production" \
  -configuration Release \
  -sdk iphoneos \
  -archivePath "build/MyApp.xcarchive" \
  CODE_SIGN_STYLE="Manual" \
  PROVISIONING_PROFILE_SPECIFIER="match AppStore"

# 2. Eksport do IPA
xcodebuild -exportArchive \
  -archivePath "build/MyApp.xcarchive" \
  -exportPath "build/ipa" \
  -exportOptionsPlist "ExportOptions.plist"

Często zadawane pytania

Ile schematów potrzeba do typowego projektu?

Zwykle wystarczą 2-3 schematy: Development (Debug), Staging (z argumentami dla serwera testowego) i Production (Release). Dla bibliotek modułowych — jeden schemat z ustawieniami do testowania. Nie mnoż schematów — każdy nowy schemat wymaga utrzymania.

Czym Scheme różni się od Build Configuration?

Build Configuration (Debug/Release) — to zestaw flag kompilatora zdefiniowanych w .xcconfig. Scheme — to zestaw akcji, z których każda odwołuje się do Build Configuration. Schemat mówi „przy uruchamianiu użyj Debug“, konfiguracja określa „Debug — to bez optymalizacji, z symbolami“.

Jak przekazać argumenty z Scheme do kodu?

Argumenty trafiają do ProcessInfo.processInfo.arguments i UserDefaults (jeśli argument zaczyna się od myślnika). Zmienne środowiskowe — do ProcessInfo.processInfo.environment. W kodzie: UserDefaults.standard.bool(forKey: "FeatureFlag") dla argumentów postaci -FeatureFlag YES.

Czy można mieć schemat dla wielu targetów?

Tak, w Build Action można dodać wiele targetów. Na przykład schemat „App + Watch + Widget“ będzie budował wszystkie trzy targety sekwencyjnie (jeśli parallelizeBuildables=NO) lub równolegle (YES). Do archiwizacji aplikacji wystarczy główny target — pozostałe są budowane jako zależności.

Po co schemat, jeśli używany jest SPM?

Swift Package Manager nie zastępuje schematów — schemat nadal określa, z jaką konfiguracją budować zależności SPM, jakie testy uruchamiać i jak archiwizować. Pakiety SPM mogą mieć własne schematy, które są automatycznie importowane do projektu po dodaniu pakietu.

Podsumowanie

  • Scheme — konfiguracja XML akcji Xcode: Build, Run, Test, Profile, Analyze, Archive.
  • Build Configuration (Debug/Release) jest ustawiana osobno dla każdej akcji schematu.
  • Schematy Shared są przechowywane w Gicie i używane przez cały zespół, private — tylko lokalnie.
  • Argumenty i zmienne środowiskowe w Scheme pozwalają przełączać środowisko bez zmiany kodu.
  • CI/CD używa Scheme przez xcodebuild -scheme, aby zagwarantować identyczność kompilacji.
  • Diagnostics (ASan, TSan, UBSan) są konfigurowane w schemacie do znajdowania błędów na etapie rozwoju.
  • Zalecenie: trzymaj 2-3 schematy Shared dla Dev/Staging/Production i nie przechowuj schematów private w repozytorium.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również