Toolset · Swift, SwiftUI, Swift Concurrency
iOS
- Swift
- SwiftUI
- async/await
Modern iOS is Swift + SwiftUI with structured concurrency. We lean on the platform where it's strong (URLSession, Codable, Keychain) and add libraries only where they earn their place.
Where two tools compete, the one marked our default is what we reach for.
Build & dependencies
2 toolsFirst-party dependency manager, integrated into Xcode. Our default — no extra tooling.
Mature dependency manager; still needed for a few libraries that lag on SPM support.
Dependency injection
2 toolsModern, compile-safe DI with a tiny footprint and SwiftUI-friendly property wrappers. Our default.
extension Container {
var apiClient: Factory<APIClient> { self { APIClient() } }
var userRepo: Factory<UserRepository> { self { UserRepository() } }
}
// use it:
@Injected(\.userRepo) private var repoEstablished, battle-tested container-based DI with dynamic registration — flexible and runtime-resolved. Because it resolves at runtime, graph errors surface as a crash at launch, not a build failure. Reach for it only when complex module composition (multiple assemblies, feature flags, dynamic module loading) is hard to express in Factory's compile-time model. Decision rule: start with Factory for its compile-time safety and modern SwiftUI integration; move to Swinject only when dynamic module composition outweighs the cost of runtime graph validation.
Networking
2 toolsThe built-in HTTP stack with native async/await; for most apps you don't need more. Use uploadTask(fromFile:) for large uploads (see the out-of-bundle blueprint). Our default.
Higher-level networking (retries, interceptors, multipart); worth it when request plumbing gets complex.
Concurrency
2 toolsasync/await, actors, and structured tasks — our default. Actors close the data-race gaps that background callbacks open.
Apple's reactive framework; still useful for streams and bindings.
Push notifications
1 toolApple Push Notification service (APNs) is the underlying transport; the first-party UserNotifications framework is our default — no extra SDKs. Handle payloads in a UNUserNotificationCenterDelegate and keep the receiver light (offload heavy work to a background task, never block the main thread). Support alert, background, and silent payload types, and register the device token against the user on your backend for targeting and analytics.
Local storage
2 toolsA robust, well-documented SQLite toolkit with record types and powerful observation. Our default for structured local data — the fine-grained control over queries (joins, custom SQL) and predictable performance it gives are essential for complex data models.
Apple's SwiftUI-native persistence layer, built on Core Data — more abstracted and opinionated, ideal for simpler models with tight SwiftUI integration. A strong contender, though its maturity and performance on complex models are still evolving. Decision rule: GRDB for complex models and fine-grained control; SwiftData for simpler models where SwiftUI integration and Apple's latest API are the priority.
Security
2 toolsErgonomic Keychain wrapper for tokens and secrets — write access and refresh tokens atomically. Our default for storing tokens and secrets.
Apple's high-level, Swift-native cryptography framework — safe APIs for hashing (SHA-256/512), symmetric encryption (AES-GCM), public-key signatures and key agreement, and Secure Enclave integration. The Swift-native counterpart to Google's Tink: reach for it whenever you need to encrypt data, verify signatures, or handle sensitive information beyond what Keychain storage covers. Our default for application-level cryptographic operations.
UI & images
2 toolsDeclarative UI — our default for new screens. Mind @MainActor isolation.
Async image downloading and caching for SwiftUI/UIKit.
Testing
2 toolsFirst-party unit and UI testing; Swift Testing is the modern macro-based successor. Our default.
BDD-style specs and expressive matchers when the team prefers that flow.
Monitoring & observability
4 toolsReal-time crash reporting with symbolicated stack traces and impact grouping. Our default for crash monitoring.
Crashes, performance traces, and release health in one product — the pick when app and backend errors share a vendor.
Apple's on-device power, performance, and crash diagnostics, delivered daily — no third-party SDK.
Unified structured logging, and signposts for measuring performance intervals in Instruments.
CI/CD
4 toolsBuild, sign (match for certificates), and ship to TestFlight/App Store. Our default for release automation.
CI on macOS runners for build/test/lint. Our default CI.
Apple's integrated CI/CD, wired into Xcode and TestFlight.
Beta distribution to internal and external testers.
Linting & formatting
3 toolsThe de-facto Swift linter — enforce style and catch issues in a build phase or CI. Our default.
Opinionated auto-formatter for Swift. Our default for formatting.
Apple's official formatter and linter for Swift.
Building on iOS?
We ship production iOSwith exactly this stack. Tell us what you're building.
Start a conversation