How do you set a language bar for a large iOS org (Swift 6, existentials, macros, concurrency)?
Mental model. A language bar is not a style guide. It is a quality system with gates, exceptions, and a migration plan.
Make it enforceable, not aspirational:
- Compiler mode per module, migrating edges inward — start with leaf modules that have no dependents.
- Lint rules for the things you actually care about: ban
anyon hot UI paths, flag@unchecked Sendableas a reviewed exception, forbid force-unwrap in new code. - Macro allowlist (Observable, Preview, test macros) so the build stays debuggable.
packagenotpublicinside the monorepo, so the API surface stays honest.- Regression gates on compile time and binary size.
The bar is a set of automated checks plus a documented exception process, reviewed quarterly. Otherwise it decays into a wiki page nobody reads.
Common traps
- Announcing the bar without tooling. If it is not enforced in CI, it is a suggestion.
- Big-bang Swift 6 migration. It stalls feature work and creates a giant branch nobody can review.
- Banning things without a replacement. “No macros” without an alternative pattern just pushes the same complexity elsewhere.
They might follow up with
- How do you roll out Swift 6 mode safely? Per-target opt-in, strict concurrency warnings first, then errors, with a burn-down dashboard.
- How do you handle exceptions? A reviewed allowlist with an owner and an expiry date — not a permanent comment.
Related questions
- 1.7.4 What are @usableFromInline and @inlinable in relation to access control?
- 1.10.2 What does Sendable mean for a Swift type you write?
- 1.10.3 Macros vs property wrappers vs result builders — one sentence each.
← You need to add a field to a public struct in a binary SPM library…