Scheme: същност, конфигурация и стартиране в Xcode

Автор: IT Sectr Публикувано: 2026-05-30 Време за четене: 9 мин

Scheme в Xcode е конфигурация, която определя как да се изгради, тества, профилира и архивира приложението за iOS, macOS, watchOS или tvOS. Всяка Scheme съдържа набор от действия (Build, Run, Test, Profile, Analyze, Archive) със собствени параметри, аргументи и променливи на средата. Според Apple Developer Documentation, 2025, Scheme е основният инструмент за управление на build конфигурациите в Xcode, като замества ръчното превключване на параметри. Xcode автоматично създава схема за всеки target при първото отваряне на проекта.

Основни положения

  • Scheme — конфигурация на Xcode с набор от действия за изграждане, тестване и архивиране.
  • Build — компилация на target-ите със зададена конфигурация (Debug или Release).
  • Run — стартиране на приложението с аргументи, променливи на средата и входна точка.
  • Test — стартиране на unit и UI тестове с избор на набор от тестове.
  • Archive — изграждане за публикуване в App Store с production конфигурация.

Какво е Scheme в Xcode?

Scheme в Xcode е XML файл (с разширение .xcscheme), който описва последователността от действия и техните параметри за изграждане и анализ на приложението. Всяка Scheme е свързана с един или повече target-и и определя с каква конфигурация (Debug, Release, AdHoc) да се изпълни всяко действие. Scheme е аналог на Build Variant в Android, но с по-гъвкава структура: една схема може да съдържа различни target-и за различни действия.

Xcode автоматично създава схема за всеки target при първото отваряне на проекта. Името на схемата по подразбиране съвпада с името на target-а. Ако в проекта има тестов target, Xcode автоматично го добавя към Test действието на схемата на основния target. За проекти с няколко target-а (основно приложение + watchOS + extension) Xcode създава отделна схема за всеки, но може да се създаде и една схема, която изгражда всички target-и наведнъж.

Схемите се съхраняват в директорията xcshareddata/xcschemes/ (за shared) или xcuserdata/<user>/xcschemes/ (за private). Shared схемите попадат в Git и се използват от целия екип. Private схемите се съхраняват локално и не се синхронизират. Файлът .xcscheme има XML формат с коренен елемент <Scheme>. Вътре има блокове за всяко действие: BuildAction, TestAction, LaunchAction, ProfileAction, AnalyzeAction, ArchiveAction.

Структура на файла .xcscheme

.xcscheme е XML файл, който може да се редактира ръчно или чрез Xcode. Основни елементи: <BuildAction> (списък на изгражданите target-и), <TestAction> (препратки към тестови target-и), <LaunchAction> (конфигурация за стартиране), <ProfileAction>, <AnalyzeAction>, <ArchiveAction>. Всеки блок съдържа атрибута buildConfiguration, който определя каква конфигурация (Debug/Release) да се използва за даденото действие.

Действия на Scheme: Build, Run, Test, Profile, Analyze, Archive

Scheme се състои от шест действия, всяко от които може да се конфигурира независимо. Build Action определя кои target-и се изграждат и в какъв ред. Run Action — как се стартира приложението: с какви аргументи, променливи на средата и с каква конфигурация. Test Action — кои тестове се изпълняват и кои опции за code coverage са включени. Profile Action — стартиране с инструментите на Instruments за профилиране. Analyze Action — статичен анализ на кода с Clang Static Analyzer. Archive Action — изграждане за публикуване в App Store или разпространение AdHoc.

За всяко действие може да се зададе отделна build configuration. Обикновено за Run и Test се използва Debug, а за Archive — Release. Build configuration определя набора от флагове на компилатора, оптимизациите и информацията за дебъгване. Xcode предоставя две стандартни конфигурации: Debug (без оптимизации, със символи за дебъгване) и Release (с оптимизации, без информация за дебъгване). Разработчикът може да добавя персонализирани конфигурации чрез project.xcconfig.

Действието Archive е особено важно — създава .xcarchive, който след това се експортира в .ipa за App Store или AdHoc. Archive Action по подразбиране използва Release конфигурацията, но може да се превключи на AdHoc или Distribution. В Archive Action е наличен и флагът revealArchiveInOrganizer — след завършване на архивирането Xcode отваря Organiser за по-нататъшни действия с архива.

xml
<!-- Пример .xcscheme для 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>

Създаване и конфигуриране на Scheme

Диагностични санитайзери

Създаването на нова схема се извършва през менюто на Xcode: Product → Scheme → New Scheme или с бутона „+“ в панела Scheme (до бутона Run). При създаването се избира target-ът, за който се създава схемата. Ако схемата е избрана като „duplicate“, Xcode автоматично копира настройките от съществуващата схема. Новите схеми по подразбиране се запазват като private — за публикуване за екипа трябва да се включи Shared в Manage Schemes.

Прозорецът Edit Scheme (Product → Scheme → Edit Scheme) съдържа шест раздела, съответстващи на броя действия. Във всеки раздел могат да се променят build configuration, аргументите за стартиране, променливите на средата и диагностичните флагове. В раздела Run са налични опциите: executable (кой бинарен файл да се стартира), wait for executable to be launched (за дебъгване на стартираните процеси), debugger (LLDB или None), launch arguments, environment variables и разширените опции (Address Sanitizer, Thread Sanitizer, Main Thread Checker, Memory Management).

За диагностика: Address Sanitizer (ASan) — открива излизане извън границите на масива, use-after-free и други грешки в паметта в C/C++/ObjC код. Thread Sanitizer (TSan) — открива състояния на състезание (data races) в многопоточен код. Undefined Behavior Sanitizer (UBSan) — разкрива недефинирано поведение, например препълване на signed int. Тези опции са налични в Edit Scheme → Run → Diagnostics и работят само за Debug компилации. Включването на всички санитайзери може да забави стартирането 2-3 пъти, затова се препоръчва включването им по избор.

Клониране на схемата за различни среди

Типична практика — създаване на отделни схеми за всяка среда: Dev, Staging, Production. Всяка схема използва същата Build Configuration (Debug за Dev, Release за Production), но различни аргументи за стартиране: -FIRAnalyticsDebugEnabled, -com.apple.CoreData.SQLDebug 1 за Dev и тяхното отсъствие за Production. Аргументите за стартиране се предават в UserDefaults (ProcessInfo.processInfo.arguments) и са достъпни за четене при стартирането на приложението. Това позволява превключване на URL на сървъра, нивото на логване и функции без промяна на кода.

Shared и private схеми: управление чрез Git

Shared схемите се съхраняват в <project>.xcworkspace/xcshareddata/xcschemes/ или <project>.xcodeproj/xcshareddata/xcschemes/ и попадат в Git хранилището. Всички разработчици от екипа виждат тези схеми в Xcode. Shared схемите са единственият начин за разпространение на схеми в екипа. Ако разработчик е създал важна схема (например „Staging Archive“), но не я е отбелязал като Shared, останалата част от екипа няма да я види, което води до объркване: всеки ще създава своя схема със свои настройки.

Private схемите се съхраняват в xcuserdata/<user>/xcschemes/ и не попадат в Git. Полезни са за лични конфигурации: например схема с включени всички санитайзери за конкретен разработчик. Private схемите не трябва да съдържат критични настройки, от които зависи изграждането на проекта — ако разработчикът напусне проекта, неговите private схеми ще изчезнат. Препоръка: всички схеми, използвани в CI/CD и от поне двама разработчици, да се правят Shared.

Управлението на схемите се извършва чрез Manage Schemes (Product → Scheme → Manage Schemes). В прозореца се показват всички схеми на проекта, техният статус (Shared/Private) и бутоните +/— за добавяне/премахване. Полето Shared превключва видимостта на схемата за екипа. При конфликт в Git (промени в .xcscheme от двама разработчици) трябва внимателно да се разреши сливането — XML файловете могат да съдържат различни идентификатори на target-и. Препоръчва се .xcscheme да се добавя към файловете, блокирани при merge (git lfs или .gitattributes).

Аргументи за стартиране и променливи на средата

Arguments в Scheme са низовете, които се предават на приложението при стартиране (ProcessInfo.processInfo.arguments), и променливите на средата (ProcessInfo.processInfo.environment). Аргументите се използват за флагове: -AppleLanguages (ru), -AppleLocale ru_RU за симулиране на руска локализация или -FIRDebugEnabled за включване на дебъгването на Firebase. Променливите на средата се прилагат за конфигурация: API_BASE_URL=http://localhost:3000, LOG_LEVEL=debug.

За управление на функциите (feature flags) в различни среди се използва комбинацията Arguments + Build Configuration. В Dev схемата се задава аргументът -FeatureFlagNewOnboarding YES, а в Production — -FeatureFlagNewOnboarding NO (или аргументът липсва). В кода проверката: UserDefaults.standard.bool(forKey: "FeatureFlagNewOnboarding"). Този подход позволява постепенно включване на функции в staging без промяна на кода и без комитване на production стойности.

Важно: аргументите и променливите на средата на Scheme презаписват стойностите от Info.plist. Ако в Info.plist е посочен API_URL, а в Scheme — API_URL=http://localhost за Run Action, при стартиране от Xcode ще се използва стойността от Scheme. При стартиране от устройството (не от Xcode) — стойността от Info.plist. Това е удобно за локална разработка, но трябва да се помни, че променливите на Scheme не влизат в компилацията — те действат само при стартиране през 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")
    }
}

// Използване при стартиране
let env = AppEnvironment()
NetworkConfig.shared.configure(baseURL: env.apiBaseURL)

Scheme в CI/CD: автоматизация чрез xcodebuild

В CI/CD (GitHub Actions, Jenkins, GitLab CI) Scheme се използва като основен аргумент на командата xcodebuild. Пример: xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Release -sdk iphoneos archive. Флагът -scheme указва коя схема да се използва. xcodebuild прочита всички настройки от файла .xcscheme, включително build configuration, target-ите и реда на изграждане. Това гарантира, че CI/CD изгражда приложението със същите параметри като локалната IDE.

За CI/CD са критични shared схемите. Ако една схема не е Shared, xcodebuild няма да я намери в хранилището и компилацията ще се провали с грешка „Scheme not found“. Правило: преди конфигурирането на CI/CD се уверете, че всички използвани схеми са отбелязани като Shared. Второ правило: в CI/CD не използвайте схемата по подразбиране (Xcode автоматично избира първата схема) — винаги предавайте името на схемата изрично чрез флага -scheme.

За паралелно изграждане на няколко схеми (например приложението и разширението watchOS) xcodebuild може да се стартира последователно или паралелно. Съвременните CI системи позволяват паралелизиране на изграждането на различни схеми чрез матрица: една задача изгражда iOS приложението, втората — разширението watchOS. Това намалява общото време за изграждане от 15 на 8 минути при два паралелни агента. Накрая артефактите се обединяват в единен .xcarchive с помощта на xcodebuild -exportArchive.

bash
#!/bin/bash — CI/CD сборка с xcodebuild
# 1. Почистване и изграждане
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. Експорт в IPA
xcodebuild -exportArchive \
  -archivePath "build/MyApp.xcarchive" \
  -exportPath "build/ipa" \
  -exportOptionsPlist "ExportOptions.plist"

Често задавани въпроси

Колко схеми са необходими за типичен проект?

Обикновено са достатъчни 2-3 схеми: Development (Debug), Staging (с аргументи за тестовия сървър) и Production (Release). За модулни библиотеки — една схема с настройки за тестване. Не създавайте много схеми — всяка нова схема изисква поддръжка.

С какво Scheme се различава от Build Configuration?

Build Configuration (Debug/Release) — набор от флагове на компилатора, дефинирани в .xcconfig. Scheme — набор от действия, всяко от които препраща към Build Configuration. Схемата казва „при стартиране използвай Debug“, конфигурацията определя, че „Debug е без оптимизации, със символи“.

Как да се предадат аргументи от Scheme в кода?

Аргументите попадат в ProcessInfo.processInfo.arguments и UserDefaults (ако аргументът започва с тире). Променливите на средата — в ProcessInfo.processInfo.environment. В кода: UserDefaults.standard.bool(forKey: "FeatureFlag") за аргументи от вида -FeatureFlag YES.

Може ли да има схема за няколко target-а?

Да, в Build Action могат да се добавят няколко target-а. Например схемата „App + Watch + Widget“ ще изгради и трите target-а последователно (ако parallelizeBuildables=NO) или паралелно (YES). За архивирането на приложението е достатъчен основният target — останалите се изграждат като зависимости.

Защо е нужна схема, ако се използва SPM?

Swift Package Manager не замества схемите — схемата продължава да определя с каква конфигурация да се изградят SPM зависимостите, кои тестове да се стартират и как да се архивира. SPM пакетите могат да имат собствени схеми, които автоматично се импортират в проекта при добавяне на пакета.

Резюме

  • Scheme — XML конфигурация на действията на Xcode: Build, Run, Test, Profile, Analyze, Archive.
  • Build Configuration (Debug/Release) се задава отделно за всяко действие на схемата.
  • Shared схемите се съхраняват в Git и се използват от целия екип, private — само локално.
  • Аргументите и променливите на средата в Scheme позволяват превключване на средата без промяна на кода.
  • CI/CD използва Scheme чрез xcodebuild -scheme, за да гарантира идентичност на компилацията.
  • Diagnostics (ASan, TSan, UBSan) се конфигурират в схемата за откриване на грешки в етапа на разработка.
  • Препоръка: дръжте 2-3 shared схеми за Dev/Staging/Production и не съхранявайте private схеми в хранилището.

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също