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 ابزار اصلی مدیریت پیکربندی‌های ساخت در 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 در اندروید است، اما با ساختاری منعطف‌تر: یک اسکیم می‌تواند 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 ایجاد می‌کند که سپس برای App Store یا AdHoc به .ipa صادر می‌شود. 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) — رفتار نامعین را آشکار می‌کند، مثلاً سرریز int علامت‌دار. این گزینه‌ها در Edit Scheme → Run → Diagnostics موجود هستند و فقط برای ساخت‌های Debug کار می‌کنند. فعال کردن همه sanitizerها می‌تواند اجرا را 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 نمی‌شوند. آن‌ها برای پیکربندی‌های شخصی مفید هستند: مثلاً اسکیمی با همه sanitizerهای فعال برای یک توسعه‌دهنده خاص. اسکیم‌های 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 برای Run Action API_URL=http://localhost — هنگام اجرا از 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 منتقل کنید.

برای ساخت موازی چند اسکیم (مثلاً برنامه و extension وی‌واچ‌اواس) می‌توان xcodebuild را به‌صورت ترتیبی یا موازی اجرا کرد. سیستم‌های CI مدرن امکان موازی‌سازی ساخت اسکیم‌های مختلف را از طریق ماتریس فراهم می‌کنند: یک job برنامه iOS را می‌سازد، دومی — extension وی‌واچ‌اواس. این زمان کل ساخت را با دو عامل موازی از 15 به 8 دقیقه کاهش می‌دهد. در پایان مصنوعات با xcodebuild -exportArchive در یک .xcarchive واحد ترکیب می‌شوند.

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 از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید