Scheme i Xcode är en konfiguration som avgör hur appen för iOS, macOS, watchOS eller tvOS byggs, testas, profileras och arkiveras. Varje Scheme innehåller en uppsättning åtgärder (Build, Run, Test, Profile, Analyze, Archive) med egna parametrar, argument och miljövariabler. Enligt Apple Developer Documentation, 2025 är Scheme det främsta verktyget för att hantera byggkonfigurationer i Xcode och ersätter manuell växling av parametrar. Xcode skapar automatiskt ett schema för varje target när projektet öppnas första gången.
Huvudpunkter
Scheme i Xcode är en XML-fil (med tillägget .xcscheme) som beskriver sekvensen av åtgärder och deras parametrar för att bygga och analysera appen. Varje Scheme är kopplad till en eller flera targets och avgör med vilken konfiguration (Debug, Release, AdHoc) varje åtgärd ska utföras. Scheme är motsvarigheten till Build Variant i Android, men med en mer flexibel struktur: ett schema kan innehålla olika targets för olika åtgärder.
Xcode skapar automatiskt ett schema för varje target när projektet öppnas första gången. Schemats standardnamn sammanfaller med targetets namn. Om projektet har en testtarget lägger Xcode automatiskt till den i Test-åtgärden för huvudtargetets schema. För projekt med flera targets (huvudapp + watchOS + extension) skapar Xcode ett separat schema för varje, men man kan också skapa ett enda schema som bygger alla targets samtidigt.
Scheman lagras i katalogen xcshareddata/xcschemes/ (för shared) eller xcuserdata/<user>/xcschemes/ (för private). Shared-scheman hamnar i Git och används av hela teamet. Private-scheman lagras lokalt och synkroniseras inte. Filen .xcscheme har XML-format med rotelementet <Scheme>. Inuti finns block för varje åtgärd: BuildAction, TestAction, LaunchAction, ProfileAction, AnalyzeAction, ArchiveAction.
.xcscheme är en XML-fil som kan redigeras manuellt eller via Xcode. Huvudelement: <BuildAction> (lista över targets att bygga), <TestAction> (referenser till testtargets), <LaunchAction> (körningskonfiguration), <ProfileAction>, <AnalyzeAction>, <ArchiveAction>. Varje block innehåller attributet buildConfiguration, som avgör vilken konfiguration (Debug/Release) som ska användas för denna åtgärd.
Scheme består av sex åtgärder som var och en kan konfigureras oberoende. Build Action avgör vilka targets som byggs och i vilken ordning. Run Action — hur appen startas: med vilka argument, miljövariabler och vilken konfiguration. Test Action — vilka tester som körs och vilka code coverage-alternativ som är aktiverade. Profile Action — körning med Instruments-verktygen för profilering. Analyze Action — statisk kodanalys med Clang Static Analyzer. Archive Action — bygge för publicering i App Store eller AdHoc-distribution.
För varje åtgärd kan en separat build configuration anges. Vanligtvis används Debug för Run och Test och Release för Archive. Build configuration avgör uppsättningen kompilatorflaggor, optimeringar och felsökningsinformation. Xcode tillhandahåller två standardkonfigurationer: Debug (utan optimering, med felsökningssymboler) och Release (med optimering, utan felsökningsinformation). Utvecklaren kan lägga till egna konfigurationer via project.xcconfig.
Åtgärden Archive är särskilt viktig — den skapar en .xcarchive som sedan exporteras till .ipa för App Store eller AdHoc. Archive Action använder som standard Release-konfigurationen, men kan växlas till AdHoc eller Distribution. I Archive Action finns också flaggan revealArchiveInOrganizer — efter arkiveringens slutförande öppnar Xcode Organiser för fortsatta åtgärder med arkivet.
<!-- Exempel på .xcscheme för iOS-app -->
<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>
Att skapa ett nytt schema görs via Xcode-menyn: Product → Scheme → New Scheme eller med knappen “+” i Scheme-panelen (bredvid Run-knappen). Vid skapandet väljs den target som schemat ska skapas för. Om schemat är valt som “duplicate” kopierar Xcode automatiskt inställningarna från det befintliga schemat. Nya scheman sparas som standard som private — för att publicera för teamet måste Shared aktiveras i Manage Schemes.
Fönstret Edit Scheme (Product → Scheme → Edit Scheme) innehåller sex flikar motsvarande antalet åtgärder. På varje flik kan man ändra build configuration, startargument, miljövariabler och diagnostiska flaggor. På fliken Run finns alternativen: executable (vilken binär som ska köras), wait for executable to be launched (för felsökning av startade processer), debugger (LLDB eller None), launch arguments, environment variables samt avancerade alternativ (Address Sanitizer, Thread Sanitizer, Main Thread Checker, Memory Management).
För diagnostik: Address Sanitizer (ASan) — upptäcker utträde utanför arraygränser, use-after-free och andra minnesfel i C/C++/ObjC-kod. Thread Sanitizer (TSan) — upptäcker datakapplöpningar (data races) i flertrådad kod. Undefined Behavior Sanitizer (UBSan) — avslöjar odefinierat beteende, till exempel overflow av en signed int. Dessa alternativ finns i Edit Scheme → Run → Diagnostics och fungerar endast för Debug-byggen. Att aktivera alla sanitizers kan fördröja starten 2-3 gånger, därför rekommenderas att aktivera dem selektivt.
Typisk praxis — att skapa separata scheman för varje miljö: Dev, Staging, Production. Varje schema använder samma Build Configuration (Debug för Dev, Release för Production), men olika startargument: -FIRAnalyticsDebugEnabled, -com.apple.CoreData.SQLDebug 1 för Dev och deras frånvaro för Production. Startargumenten överförs till UserDefaults (ProcessInfo.processInfo.arguments) och är tillgängliga för läsning vid appens start. Detta gör det möjligt att växla server-URL, loggningsnivå och funktioner utan kodändring.
Shared-scheman lagras i <project>.xcworkspace/xcshareddata/xcschemes/ eller <project>.xcodeproj/xcshareddata/xcschemes/ och hamnar i Git-repot. Alla utvecklare i teamet ser dessa scheman i Xcode. Shared-scheman är det enda sättet att sprida scheman inom teamet. Om en utvecklare har skapat ett viktigt schema (till exempel “Staging Archive”) men inte markerat det som Shared, kommer resten av teamet inte att se det, vilket leder till förvirring: alla kommer att skapa sitt eget schema med egna inställningar.
Private-scheman lagras i xcuserdata/<user>/xcschemes/ och hamnar inte i Git. De är användbara för personliga konfigurationer: till exempel ett schema med alla sanitizers aktiverade för en specifik utvecklare. Private-scheman bör inte innehålla kritiska inställningar som bygget av projektet är beroende av — om utvecklaren lämnar projektet försvinner hans private-scheman. Rekommendation: gör alla scheman som används i CI/CD och av minst två utvecklare till Shared.
Hanteringen av scheman sker via Manage Schemes (Product → Scheme → Manage Schemes). I fönstret visas alla scheman i projektet, deras status (Shared/Private) samt knapparna +/— för att lägga till/ta bort. Kryssrutan Shared växlar schemats synlighet för teamet. Vid en Git-konflikt (ändringar i .xcscheme från två utvecklare) måste sammanfogningen lösas noggrant — XML-filer kan innehålla olika targetidentifierare. Det rekommenderas att lägga till .xcscheme i filer som låses vid merge (git lfs eller .gitattributes).
Arguments i Scheme är de strängar som skickas till appen vid start (ProcessInfo.processInfo.arguments) och miljövariabler (ProcessInfo.processInfo.environment). Argument används för flaggor: -AppleLanguages (ru), -AppleLocale ru_RU för att simulera rysk lokalisering eller -FIRDebugEnabled för att aktivera Firebase-felsökning. Miljövariabler tillämpas för konfiguration: API_BASE_URL=http://localhost:3000, LOG_LEVEL=debug.
För att hantera funktioner (feature flags) i olika miljöer används kombinationen Arguments + Build Configuration. I Dev-schemat ställs argumentet -FeatureFlagNewOnboarding YES in och i Production — -FeatureFlagNewOnboarding NO (eller så saknas argumentet). I koden kontrollen: UserDefaults.standard.bool(forKey: “FeatureFlagNewOnboarding”). Detta tillvägagångssätt gör det möjligt att gradvis aktivera funktioner i staging utan kodändring och utan att commit:a produktionsvärden.
Viktigt: Schemes argument och miljövariabler åsidosätter värdena i Info.plist. Om API_URL anges i Info.plist och API_URL=http://localhost i Scheme för Run Action, används värdet från Scheme när appen startas från Xcode. Vid start från enheten (inte från Xcode) — värdet från Info.plist. Detta är bekvämt för lokal utveckling, men kom ihåg att Scheme-variabler inte kommer med i bygget — de verkar endast vid start via Xcode.
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")
}
}
// Används vid start
let env = AppEnvironment()
NetworkConfig.shared.configure(baseURL: env.apiBaseURL)
I CI/CD (GitHub Actions, Jenkins, GitLab CI) används Scheme som huvudargument för kommandot xcodebuild. Exempel: xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -configuration Release -sdk iphoneos archive. Flaggan -scheme anger vilket schema som ska användas. xcodebuild läser alla inställningar från .xcscheme-filen, inklusive build configuration, targets och byggordning. Detta garanterar att CI/CD bygger appen med samma parametrar som den lokala IDE:n.
För CI/CD är shared-scheman kritiska. Om ett schema inte är Shared hittar inte xcodebuild det i repot och bygget misslyckas med felet “Scheme not found”. Regel: innan CI/CD konfigureras, se till att alla använda scheman är markerade som Shared. Andra regeln: använd inte standardschemat i CI/CD (Xcode väljer automatiskt det första schemat) — skicka alltid schemats namn explicit via flaggan -scheme.
För parallella byggen av flera scheman (till exempel appen och watchOS-tillägget) kan xcodebuild köras sekventiellt eller parallellt. Moderna CI-system gör det möjligt att parallellisera bygget av olika scheman via en matris: ett job bygger iOS-appen, det andra — watchOS-tillägget. Detta minskar den totala byggtiden från 15 till 8 minuter med två parallella agents. I slutet kombineras artefakterna till en enda .xcarchive med hjälp av xcodebuild -exportArchive.
#!/bin/bash — CI/CD-bygge med xcodebuild
# 1. Rensa och bygga
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. Exportera till IPA
xcodebuild -exportArchive \
-archivePath "build/MyApp.xcarchive" \
-exportPath "build/ipa" \
-exportOptionsPlist "ExportOptions.plist"
Vanliga frågor
Vanligtvis räcker 2-3 scheman: Development (Debug), Staging (med argument för testservern) och Production (Release). För modulära bibliotek — ett schema med inställningar för testning. Multiplicera inte scheman — varje nytt schema kräver underhåll.
Build Configuration (Debug/Release) — en uppsättning kompilatorflaggor definierade i .xcconfig. Scheme — en uppsättning åtgärder, där var och en refererar till en Build Configuration. Schemat säger “använd Debug vid start”, konfigurationen definierar att “Debug är utan optimering, med symboler”.
Argument hamnar i ProcessInfo.processInfo.arguments och UserDefaults (om argumentet börjar med ett bindestreck). Miljövariabler hamnar i ProcessInfo.processInfo.environment. I koden: UserDefaults.standard.bool(forKey: “FeatureFlag”) för argument av formen -FeatureFlag YES.
Ja, i Build Action kan flera targets läggas till. Till exempel bygger schemat “App + Watch + Widget” alla tre targets sekventiellt (om parallelizeBuildables=NO) eller parallellt (YES). För att arkivera appen räcker huvudtarget — de andra byggs som beroenden.
Swift Package Manager ersätter inte scheman — schemat avgör fortfarande med vilken konfiguration SPM-beroendena ska byggas, vilka tester som ska köras och hur arkivering sker. SPM-paket kan ha egna scheman som automatiskt importeras till projektet när paketet läggs till.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också