SweetPad Documentation

repository·main·Indexed 23 days ago

https://github.com/sweetpad-dev/sweetpad

A suite of tools for developing Swift/iOS projects (iOS, macOS, tvOS, watchOS, and visionOS) without the Xcode IDE. It includes a VS Code extension for editor-integrated build, run, debug, and test workflows, and the sweetpad-cli, a native binary for terminal-based automation and CI/CD that provides JSON output for structured data parsing.

Tokens
86.2K
Snippets
125
Records
483
Agent score
83%

What's inside SweetPad

  1. Overview of SweetPad tools

    main

    SweetPad is a suite of tools designed for developing Swift/iOS projects (iOS, macOS, tvOS, watchOS, and visionOS) outside of the Xcode IDE. It provides two primary interfaces:

    1. VS Code Extension: An editor-centric workflow with sidebar controls, logs, and testing integration.
    2. SweetPad CLI: A native binary ("xcodebuild for humans") for terminal-based workflows, automation, and CI/CD, featuring JSON output for easy parsing.
  2. Overview of sweetpad-lib

    main

    ⚠️ Internal Use Only

    sweetpad-lib is an internal implementation detail of the SweetPad VS Code extension. It is shipped as an N-API native addon (@sweetpad/lib). It has no stable API and no semver guarantees for external consumers.

    Purpose

    sweetpad-lib is a Rust-based resolver designed to compute Xcode build settings and compiler arguments. Unlike tools that observe build logs (which can be stale or inaccurate), sweetpad-lib derives settings directly from the project files (pbxproj, xcconfig, etc.).

    Core Layers

    1. Settings Resolver: Converts pbxproj, xcconfig, and xcspec into a resolved build-settings dictionary (validated against xcodebuild -showBuildSettings).
    2. Argument Resolver: Computes per-tool command-line arguments (e.g., for swiftc, clang, or the linker) based on the resolved settings.
    3. BSP Server: Provides editor intelligence via the Build Server Protocol (BSP), connecting the compiler arguments to sourcekit-lsp for use in editors like VS Code or Cursor.
  3. Introduction to SweetPad

    main

    SweetPad is a toolset designed to help you build, run, debug, and test Xcode projects for iOS, macOS, tvOS, watchOS, and visionOS without needing to use the Xcode IDE. It supports Xcode workspaces, Xcode projects, Tuist, XcodeGen, and Swift Packages.

    SweetPad is available in two primary forms:

    1. VSCode Extension: Provides a GUI-driven experience within VSCode (or Cursor) via a sidebar. It includes integrated logs, testing panels, formatting, and autocomplete.
    2. SweetPad CLI: A command-line tool (sweetpad) designed for terminal-based workflows, scripting, git hooks, and CI/CD.

    Requirement: Both the extension and the CLI drive Xcode's command-line tools under the hood, so Xcode must be installed on your Mac.

  4. Overview of SweetPad features

    main

    SweetPad provides a suite of tools for Swift/iOS development in VS Code or Cursor, including:

    • Autocomplete: Set up using xcode-build-server.
    • Build & Run: Build and run applications using xcodebuild.
    • Format: Format files using swift-format or other chosen formatters.
    • Simulator: Manage iOS simulators.
    • Devices: Run iOS applications on physical iPhone or iPad devices.
    • Tools: Manage essential iOS development tools via Homebrew.
    • Debug: Debug iOS applications using CodeLLDB.
    • Tests: Run tests on both simulators and physical devices.
  5. Understand the SweetPad feature coverage matrix

    main

    The feature coverage matrix tracks which Xcode build-system features are exercised by the project's test corpus. It is used to verify that the settings oracle can correctly resolve complex build configurations.

    Legend:

    • ✅: At least one fixture exercises this feature.
    • ❌: Known gap in coverage.
    • 🚫: Explicitly out of scope.
    • ◐: Partially covered or incremental.

    Key coverage areas include:

    • Project Shapes: Single .xcodeproj, .xcworkspace (single or multiple projects), nested sub-projects, Swift Package Manager (SPM) root projects, and Xcode 16+ Buildable Folders.
    • Build Output Locations: Modeling of BUILD_DIR, OBJROOT, and DERIVED_DATA_DIR based on various DerivedDataLocationStyle and BuildLocationStyle settings.
    • Target/Product Types: iOS, macOS, watchOS, tvOS, visionOS, Dynamic/Static frameworks, Static libraries, Resource bundles, and various App Extensions.
    • Configurations & xcconfig: Debug/Release, custom configurations, .xcconfig inheritance, and conditional settings.
    • Settings Inheritance: $(inherited) propagation, variable substitution (e.g., $(SRCROOT), $(TARGET_NAME)), and modifier syntax (e.g., ${VAR:default=...}).
    • Schemes: Shared and user schemes, environment variables, launch arguments, and custom test plans.
    • SDKs & Architectures: Support for iphoneos, iphonesimulator, macosx, watchos, xros (visionOS), and architectures like arm64, x86_64, and arm64e.
    • Linking & Resources: Framework embedding, static/dynamic linking, Asset Catalogs, xcstrings, and Privacy Manifests.
    • Swift Specifics: Mixed Swift/ObjC targets, bridging headers, Swift macros, and strict concurrency.
  6. Explore the SweetPad sidebar interface

    main

    Once a compatible project is opened, the SweetPad sidebar (accessed via the 🍭 icon) provides three main functional sections:

    • Build: Lists your available schemes. Each scheme has a ▶️ button used to trigger the build and run process.
    • Destinations: Displays available targets for running your app, including simulators, connected physical devices, and macOS.
    • Tools: Provides a one-click installation interface for helper tools required by SweetPad (e.g., xcbeautify).
  7. Understand the SweetPad CLI positioning and design

    main

    The sweetpad CLI is a standalone, headless command-line interface designed as "xcodebuild for humans." It serves as a native front-end to the sweetpad-lib Rust engine, allowing you to run, build, and explore Xcode projects from a terminal or CI environment without needing an editor or a Node.js runtime.

    Key Characteristics:

    • Standalone & Headless: Unlike previous iterations that only controlled the VS Code extension, this CLI can drive Xcode projects independently.
    • Human-Friendly: Provides sane discovery, readable output, and interactive pickers while remaining fully scriptable.
    • Resource-First Grammar: Uses a sweetpad <resource> <action> [flags] pattern (e.g., sweetpad simulator list).
    • Dual Purpose: It contains both the standalone headless commands and the vscode namespace (a JSON-RPC client for controlling the VS Code extension).
  8. SweetPad Library Roadmap and Correctness Goals

    main

    The sweetpad-lib project aims for 100% structural correctness compared to xcodebuild. The roadmap is organized into several tracks:

    • Track A (Settings): Closing gaps in coverage mapping (e.g., CLANG_COVERAGE_MAPPING) and auditing skipped corpus captures.
    • Track B (Geometry): Reaching the 'canonical ceiling' for machine-specific paths.
    • Track C (Compiler Args): Fixing itemized structural gaps in compiler-args (e.g., visionOS coverage, .mm source handling, and version-specific flags).
    • Track D (Corpus Expansion): Expanding support for XPC services, weak/optional framework links, and other project types.
    • Track E (Harness Hardening): Improving the testing and validation infrastructure.
  9. Determine the scope of settings resolution

    main

    When using SweetPad for settings resolution, it is important to distinguish between what is resolvable from project inputs and what is not.

    In Scope (Derivable from pbxproj/xcconfig + Apple defaults):

    • Standard build settings.
    • Signing settings that are pass-through or per-SDK/platform defaults (e.g., DEVELOPMENT_TEAM, CODE_SIGN_IDENTITY defaults like - on simulators, CODE_SIGN_STYLE, ENABLE_HARDENED_RUNTIME, and maccatalyst. prefixes).

    Out of Scope (Requires environment/machine state):

    • "Real signing" data: EXPANDED_CODE_SIGN_IDENTITY, PROVISIONING_PROFILE_SPECIFIER, or resolved profile UUIDs.
    • Anything requiring access to the Mac keychain, ~/Library/MobileDevice/Provisioning Profiles/, or specific Xcode user accounts.
    • CocoaPods/Carthage integration and archive/release-signed builds.
  10. Understand Hot Reload limitations and quirks

    main

    Hot reload via SweetPad (using InjectionNext) allows for live updates of certain code elements without a full relaunch, but it has specific constraints regarding memory layout and symbol binding.

    What you can change live

    • Function bodies (func, init that doesn't mutate stored properties, computed property getters, subscript getters).
    • The contents of a SwiftUI view's body.
    • Closure bodies (including escaping closures captured in @State arrays, etc.).
    • Constants declared inside a function.

    What requires a relaunch

    If you modify any of the following, you must rebuild and relaunch the app because the memory layout or symbol names change:

    • Stored properties: Adding, removing, or renaming a stored property (e.g., var x: Int, @State var name).
    • Class methods: Adding, removing, or reordering methods on a non-final class (changes vtable layout).
    • Function signatures: Changing parameter types, return types, or throws-ness.
    • App Entry Point: Modifying @main or the App body.
    • Generics: Changing generic constraints.
    • Top-level code: File-scope lets or global functions outside a type.
    • Swift Package dependencies: Unless the package was specifically built with -Xlinker -interposable in its linkerSettings.

    Platform Support

    • Supported: iOS Simulator, tvOS Simulator, visionOS Simulator, and macOS.
    • Not Supported: Physical devices (due to DYLD_INSERT_LIBRARIES stripping) and watchOS Simulator.

    Performance and State

    • Performance: Using the -interposable flag adds a small overhead (similar to a C library call) to every Swift function call. This is negligible for UI code but measurable in hot inner loops. Do not ship Release builds with this flag enabled. SweetPad only injects this flag when sweetpad.hotReload.enabled is true.
    • State Preservation: Hot reload preserves @State, @StateObject, @AppStorage, and other stored data. However, if you change a stored property's type, the in-memory instance will still use the old layout, leading to undefined behavior. Relaunch to fix.
  11. Understand the SweetPad CLI output models

    main

    The CLI provides different output formats depending on your needs:

    • Beautified Output: By default, build and test commands provide a concise, colorized stream of events (compile, link, sign, diagnostic, etc.) without requiring external dependencies like xcbeautify.
    • Raw Output: Use the -v flag to pass raw output through without beautification.
    • JSON Output: Use the --json flag for machine-readable output. This is useful for CI/CD or integration with other tools.
    • NDJSON Stream: Use the -o ndjson flag to output a Newline Delimited JSON stream.