If you found this helpful, you can support more open source work!

Production-ready reducer patterns and dependencies for The Composable Architecture.
- Philosophy
- Installation
- Requirements
- Reducer Modules
- Dependency Modules
- Privacy Manifest
- Contributing
- Acknowledgments
- License
These are production-ready patterns extracted from real TCA applications. Each module solves a common problem with minimal API surface and maximum composability.
Add the package to your Package.swift:
dependencies: [
.package(url: "https://github.com/mehmetbaykar/swift-composable-architecture-extras.git", from: "1.0.0")
]Then add the product to your target:
.target(
name: "YourTarget",
dependencies: [
.product(name: "ComposableArchitectureExtras", package: "swift-composable-architecture-extras")
]
)| Platform | Minimum Version |
|---|---|
| iOS | 13.0+ |
| macOS | 10.15+ |
| tvOS | 13.0+ |
| watchOS | 6.0+ |
| Swift | 6.2+ |
| TCA | 1.23.1+ |
A generic analytics reducer that handles provider integration using a declarative result builder syntax. Define events once, track everywhere.
AnalyticsReducerOf<Self, AppEvent> { state, action in
switch action {
case .viewAppeared: .screenViewed(name: "Home")
case .dismissed: []
}
}A reducer modifier that conditionally executes the wrapped reducer based on state and action predicates. Perfect for feature flags, boundary enforcement, and action gating.
Reduce { state, action in
// Business logic
}
.filter { state, action in
state.isFeatureEnabled
}A declarative form validation system with automatic error state management. Define validation rules once, get real-time feedback on every field change.
FormValidationReducer(
submitAction: \.submitTapped,
onFormValidatedAction: .loginSucceeded,
validations: [
FieldValidation(field: \.email, errorState: \.emailError, rules: [.nonEmpty(fieldName: "Email")])
]
)A universal haptics module that provides state-triggered haptic feedback across iOS, macOS, and watchOS. Trigger haptics declaratively when state changes.
Reduce { state, action in
// Business logic
}
.haptics(.selection, triggerOnChangeOf: \.selectedIndex)
.haptics(.impactMedium(), triggerOnChangeOf: \.count, isEnabled: \.hapticsEnabled)Debug printing utilities with customizable action filtering and formatted output.
Reduce { state, action in
// Business logic
}
._printChanges(.prettyConsole(
allowedActions: .not(.init { if case .binding = $0 { true } else { false } }),
showTimestamp: true
))Prevents device screen from auto-locking during specific app states. Works across iOS, tvOS, macOS, and watchOS with platform-appropriate implementations.
Reduce { state, action in
// Business logic
}
.screenAwake(when: \.isPlaying)State-triggered screen brightness control for TCA applications. Automatically adjusts screen brightness based on state changes with smart restoration to original brightness.
Reduce { state, action in
// Business logic
}
.screenBrightness(level: \.brightnessLevel)Platform Support: iOS only. macOS, watchOS, and tvOS compile but are no-ops (no public brightness APIs exist).
A lightweight TCA dependency for accessing app bundle metadata including version strings, build numbers, and bundle identifiers.
@Dependency(\.appInfo) var appInfo
let version = appInfo.appVersion()
let build = appInfo.buildNumber()
let bundleId = appInfo.bundleIdentifier()A cross-platform TCA dependency for accessing device system information: CPU usage, memory, disk storage, battery, network connectivity, thermal state, low power mode, device identity (including core counts and isiOSAppOnMac), screen info (resolution, scale, PPI, notch/Dynamic Island detection), and jailbreak detection (iOS).
@Dependency(\.deviceInfo) var deviceInfo
let identity = await deviceInfo.identity()
let cpu = await deviceInfo.cpu()
let memory = deviceInfo.memory()
let disk = deviceInfo.disk()
let thermal = deviceInfo.thermalState()
let lowPower = deviceInfo.isLowPowerModeEnabled()
#if !os(tvOS)
let battery = await deviceInfo.battery()
#endif
#if !os(watchOS)
let network = await deviceInfo.network()
#endif
#if !os(visionOS)
let screen = await deviceInfo.screen()
#endifPlatform Support: iOS, macOS, tvOS, watchOS. Battery excluded on tvOS, network excluded on watchOS. Screen excluded on visionOS. Jailbreak detection iOS only.
A cross-platform TCA dependency for opening system settings. Platform-specific enum cases ensure consumers only see options their platform supports.
@Dependency(\.openSettings) var openSettings
await openSettings.open(.general)A cross-platform TCA dependency for opening URLs externally or in-app via SFSafariViewController (iOS).
@Dependency(\.customOpenURL) var openURL
// Open externally (all platforms)
await openURL(URL(string: "https://example.com")!)
// Open in-app (iOS only)
#if os(iOS)
await openURL(URL(string: "https://example.com")!, prefersInApp: true)
#endifPlatform Support: iOS (external + in-app), macOS, tvOS, visionOS (external only). watchOS excluded.
This package includes a PrivacyInfo.xcprivacy privacy manifest as required by Apple for third-party SDKs.
| Category | Reason Code | Usage |
|---|---|---|
Disk Space (NSPrivacyAccessedAPICategoryDiskSpace) |
85F4.1 |
DeviceInfo module queries disk capacity via URLResourceKey to display storage information to the user |
File Timestamp (NSPrivacyAccessedAPICategoryFileTimestamp) |
C617.1 |
DeviceInfo module's jailbreak detection (iOS only) uses FileManager.attributesOfItem(atPath:) which internally calls stat() |
The privacy manifest bundled with this package covers the APIs used by the package itself. If your app uses the Analytics module with real analytics providers (Firebase, Amplitude, etc.), you must declare any applicable NSPrivacyCollectedDataTypes in your app's own privacy manifest.
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
Built on top of The Composable Architecture by Point-Free.
This project is licensed under the MIT License. See LICENSE for details.