Skip to content
Install

How sochi works

The ideas behind sochi, the Apple tools it calls, and where to start in the code.

Xcode is the source of truth. sochi has no hand-written lists of Apple’s data. Templates, the capability catalog, entitlement and Info.plist schemas, and product types all come from the selected Xcode when sochi runs. A new Xcode brings new capabilities and templates with no sochi update.

Remember choices, never settings. sochi saves the scheme and team you picked, and nothing else. Build settings are read from xcodebuild every time.

Every edit is checked or undone. Edits are planned first, shown as a diff, written atomically, then checked against xcodebuild. If a check fails, every file goes back.

Your project stays an Xcode project. No generator, no new format. sochi edits project.pbxproj in place in Xcode’s own style, so Xcode and sochi can take turns on the same project.

Status on stderr, app on stdout. You can pipe sochi run into other tools.

Tool Used for
xcodebuild Building, listing schemes and targets, reading build settings, resolving packages.
xcrun devicectl Listing devices, checking installed apps, installing, launching with the console attached.
xcrun simctl Listing, booting, installing on and launching simulators.
swift package dump-package Reading a package’s products.
git ls-remote Finding a package’s newest release tag.
xcode-select, defaults Finding Xcode, and the teams signed into it.

Signing is Xcode’s automatic signing, through xcodebuild -allowProvisioningUpdates. sochi doesn’t use the App Store Connect API, libimobiledevice, XcodeProj or Tuist.

sochi is a Swift 6 package that needs macOS 14 or later. Its only dependency is swift-argument-parser.

Target Role
sochi The command-line interface: commands, options, terminal output.
SochiKit Everything else.
SochiKitTests Swift Testing suites. Many read the installed Xcode.

Session holds one project, scheme and destination.

  1. XcodeProject finds the project.
  2. The scheme, device and team are resolved, from your options first, then saved choices, then detection.
  3. Xcodebuild builds into sochi’s own DerivedData, and BuildLog turns the output into tasks, diagnostics and results.
  4. AppBundle checks the product, ProjectState decides whether to install, and devicectl or simctl launch it.

ProjectEditor plans an edit as an EditPlan, then applies it. Parts it relies on:

  • PBXProjectFile reads project.pbxproj, and PBXEditor and PBXTextWriter make targeted text edits in Xcode’s layout.
  • CapabilityCatalog, CapabilityWriter and EntitlementSchema handle capabilities.
  • TemplateIndex, TemplateEngine and TemplatePlanner run Xcode’s .xctemplates. ProjectCreator does the same for sochi new.
  • XcodeSpecs reads product types and embed rules from Xcode’s .xcspec files.
  • Migration, MigrationVerifier and Reorganizer handle sochi migrate.
  • PackageManager, PackageSpec and PackageResolver handle packages and sochi.toml.
Terminal window
git clone https://github.com/Chandram-Dutta/sochi.git
cd sochi
swift build
swift test
  • Put behaviour in SochiKit, and only the command wiring in sochi.
  • When something needs Apple data, read it from Xcode rather than adding a list.
  • The tests compare sochi’s output with projects that Xcode itself created, in Fixtures/Golden. Fixtures/Classic is an old group-based project for the migration tests.
  • scripts/build-release.sh 0.1.0 builds a universal release binary into dist/ for a local check.

Releases are made by publishing a GitHub release with a tag such as v0.1.0. A workflow builds the binary, attaches it with its checksum, and updates the Homebrew formula.