Architecture Overview
Nuance iOS er bygget med The Composable Architecture (TCA) og en modulær Swift Package Manager struktur med 35 library targets.
Arkitektur-principper
┌─────────────────────────────────────────────────────────┐
│ App Target │
│ (Nuance.xcodeproj) │
└─────────────────────────┬───────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────┐
│ Feature Layer │
│ AppFeature → AuthenticationFeature → LoggedInFeature │
│ HomeFeature, TaskFeature, ProfileFeature │
└─────────────────────────┬───────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────┐
│ Client Layer │
│ APIClient, SessionClient, AnalyticsClient, etc. │
│ (Protocol interfaces - no implementations) │
└─────────────────────────┬───────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────┐
│ Implementation Layer │
│ APIClientLive, AnalyticsClientMixpanel, ErrorClientSentry │
│ (Concrete implementations) │
└─────────────────────────┬───────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────┐
│ Shared Layer │
│ SharedModels, Styleguide, SwiftUIHelpers, Helpers │
└─────────────────────────────────────────────────────────┘Feature Modules
Features indeholder UI + business logic med TCA reducers.
| Modul | Ansvar |
|---|---|
AppFeature | Root coordinator, app-level state machine |
AuthenticationFeature | Login, register, onboarding flows |
LoggedInFeature | Tab navigation container |
HomeFeature | Home dashboard |
TaskFeature | Task management |
CoursesFeature | Course content og progression |
CommunityFeature | Community features |
ProfileFeature | User profile |
SettingsFeature | App settings |
PaywallFeature | Subscription og in-app purchases |
SplashFeature | App launch splash screen |
BrainDumpFeature | Voice-to-task brain dump |
Client Protocols
Dependency interfaces - ingen implementationer, kun protokoller.
| Modul | Ansvar |
|---|---|
APIClient | Domain-level API interface (~80 endpoint signatures) |
SessionClient | Authentication state management |
AnalyticsClient | Event tracking interface |
ErrorClient | Error reporting interface |
KeychainClient | Secure storage |
UserDefaultsClient | Local preferences |
AudioPlayerClient | Audio playback |
AudioRecorderClient | Voice recording |
SpeechRecognitionClient | Speech-to-text |
RevenueCatClient | Subscription management |
PlatformAuthenticationClient | OAuth (Google Sign-In) |
RemoteNotificationsClient | Push notifications |
UserNotificationClient | Local notifications |
Live Implementations
Konkrete implementationer af client protocols.
| Modul | Implementerer | Ekstern dependency |
|---|---|---|
APIClientLive | APIClient | OpenAPI Generator |
AnalyticsClientMixpanel | AnalyticsClient | Mixpanel SDK |
ErrorClientSentry | ErrorClient | Sentry SDK |
PlatformAuthenticationClientLive | PlatformAuthenticationClient | Google Sign-In |
AudioRecorderClientLive | AudioRecorderClient | AVFoundation |
SpeechRecognitionClientLive | SpeechRecognitionClient | Speech framework |
Shared Infrastructure
| Modul | Ansvar |
|---|---|
SharedModels | Domain entities (User, Course, AppTask, etc.) |
Styleguide | Design system, fonts, colors |
SwiftUIHelpers | Reusable UI components |
Helpers | TCA utilities og extensions |
Data Flow
User Action
│
▼
┌─────────────┐
│ View │ SwiftUI
└──────┬──────┘
│ .send(.view(.buttonTapped))
▼
┌─────────────┐
│ Reducer │ TCA - Pure business logic
└──────┬──────┘
│ Effect
▼
┌─────────────┐
│ Client │ Dependency protocol
└──────┬──────┘
│
▼
┌─────────────┐
│ Live │ Concrete implementation
└──────┬──────┘
│
▼
External API / SDKTCA Reducer Pattern
swift
@Reducer
struct FeatureReducer {
@ObservableState
struct State: Equatable {
var isLoading = false
var items: [Item] = []
}
enum Action {
case view(View) // UI events
case delegate(Delegate) // Parent communication
case `internal`(Internal) // Private actions
enum View {
case onAppear
case refreshTapped
}
}
@Dependency(\.apiClient) var api
var body: some ReducerOf<Self> {
Reduce { state, action in
switch action {
case .view(.onAppear):
state.isLoading = true
return .run { send in
let items = try await api.getItems()
await send(.internal(.itemsLoaded(items)))
}
// ...
}
}
}
}API Contract
API client genereres automatisk fra OpenAPI spec:
- Spec:
Sources/APIClientLive/openapi.yaml(3350 lines, 52 operationIds) - Generator: Swift OpenAPI Generator plugin
- Mapping:
Sources/APIClientLive/Mappings/- DTO → Domain conversions
Se API Endpoints for komplet reference (44 exposed / 52 total).
Navigation
Forstå TCA Development skill for dybere patterns.