# iOS Arxitektura 7: TCA (The Composable Architecture) — Point-Free'ning Zamonaviy Yondashuvi

> **Holat:** 2026-yil oktabr. TCA bugungi kunda SwiftUI ilovalari uchun eng kuchli va keng tarqalgan state management va arxitektura yechimlaridan biriga aylangan.

## Mundarija
1. [TCA nima?](#tca-nima)
2. [TCA tarkibiy qismlari](#tarkibiy-qismlar)
3. [Data Flow (Ma'lumotlar oqimi)](#data-flow)
4. [Amaliy loyiha: Counter](#amaliy-loyiha)
5. [Effect'lar bilan ishlash (API Call)](#effects)
6. [Composition (Kompozitsiya)](#composition)
7. [Navigation TCA'da](#navigation)
8. [Testing TCA](#testing)
9. [TCA qachon ishlatiladi va uning kamchiliklari](#qachon-ishlatish)
10. [Xulosa](#xulosa)
11. [Manbalar](#manbalar)

## 1. TCA nima? {#tca-nima}

**The Composable Architecture (TCA)** — Point-Free (Brandon Williams va Stephen Celis) tomonidan yaratilgan bo'lib, SwiftUI va Swift ilovalari uchun maxsus ishlab chiqilgan arxitektura kutubxonasidir.

- **Asosiy g'oya:** Unidirectional data flow (bir yo'nalishli ma'lumot oqimi).
- **Tarqalishi:** GitHub'da juda mashhur (12,000+ yulduzlar) va ko'plab yirik production ilovalarda ishlatiladi.
- **Maqsad:** State boshqaruvini barqarorlashtirish, kompozitsiya orqali modullilikni oshirish va test qilishni mutlaqo deterministik qilish.

## 2. TCA tarkibiy qismlari {#tarkibiy-qismlar}

TCA asosan bir nechta fundamental tushunchalardan iborat:

- **State:** Ekranning yoki modulning joriy holati. Odatda `struct` ko'rinishida yoziladi va o'zgaruvchilarni saqlaydi.
- **Action:** Foydalanuvchi harakatlari (masalan, tugma bosilishi) va tizim hodisalari (masalan, API javobi kelishi). Odatda `enum`.
- **Reducer:** State va Action ni qabul qilib, yangi State ni qaytaruvchi sof funksiya.
- **Store:** State ni o'zida saqlaydi va Action'larni qabul qilib Reducer orqali State ni yangilaydi.
- **Effect:** Asinxron operatsiyalar (API chaqiruvlari, taymerlar va hk). Ular oxir-oqibat yana Action qaytaradi.
- **Dependencies (yangi Environment):** Tashqi bog'lanishlar va servislar.

## 3. Data Flow (Ma'lumotlar oqimi) {#data-flow}

TCA'da ma'lumotlar oqimi bir yo'nalishli va doiraviy:

![The Composable Architecture (TCA) Data Flow](/lessons/images/architecture/arch_07_tca_flow.svg)

## 4. Amaliy loyiha: Counter {#amaliy-loyiha}

Eng oddiy TCA namunasi - bu Counter. `@Reducer` va `@ObservableState` makrolari (Swift 5.9+ / TCA modern) orqali kodingiz ancha qisqaradi.

```swift
import SwiftUI
import ComposableArchitecture

@Reducer
struct CounterFeature {
    // 1. State
    @ObservableState
    struct State: Equatable {
        var count = 0
    }
    
    // 2. Action
    enum Action {
        case incrementButtonTapped
        case decrementButtonTapped
    }
    
    // 3. Reducer
    var body: some ReducerOf<Self> {
        Reduce { state, action in
            switch action {
            case .incrementButtonTapped:
                state.count += 1
                return .none // Effect qaytarmaydi
                
            case .decrementButtonTapped:
                state.count -= 1
                return .none
            }
        }
    }
}

// 4. View
struct CounterView: View {
    // Store obyekti View'ga beriladi
    let store: StoreOf<CounterFeature>
    
    var body: some View {
        VStack(spacing: 20) {
            Text("\(store.count)")
                .font(.largeTitle)
                
            HStack {
                Button("-") {
                    store.send(.decrementButtonTapped)
                }
                .font(.largeTitle)
                
                Button("+") {
                    store.send(.incrementButtonTapped)
                }
                .font(.largeTitle)
            }
        }
        .padding()
    }
}
```

## 5. Effect'lar bilan ishlash (API Call) {#effects}

Asinxron ishlarni bajarish (API chaqiruvlari, bazadan o'qish) uchun `Effect` ishlatiladi. `Effect.run` yoki qisqacha `.run` orqali asinxron blok yoziladi va u yana yangi `Action` qaytaradi.

![TCA Side Effects va Dependencies Boshqaruvi](/lessons/images/architecture/arch_07_tca_effects.svg)

```swift
import SwiftUI
import ComposableArchitecture

@Reducer
struct UserListFeature {
    @ObservableState
    struct State: Equatable {
        var users: [String] = []
        var isLoading = false
    }
    
    enum Action {
        case fetchUsersTapped
        case usersResponse([String])
    }
    
    var body: some ReducerOf<Self> {
        Reduce { state, action in
            switch action {
            case .fetchUsersTapped:
                state.isLoading = true
                return .run { send in
                    // 1. Asinxron operatsiya (masalan, API call)
                    try await Task.sleep(for: .seconds(2))
                    let fetchedUsers = ["Ali", "Vali", "Hasan"]
                    
                    // 2. Natijani yuborish
                    await send(.usersResponse(fetchedUsers))
                }
                
            case let .usersResponse(users):
                state.isLoading = false
                state.users = users
                return .none
            }
        }
    }
}

struct UserListView: View {
    let store: StoreOf<UserListFeature>
    
    var body: some View {
        List {
            if store.isLoading {
                ProgressView()
            } else {
                ForEach(store.users, id: \.self) { user in
                    Text(user)
                }
            }
            
            Button("Users Olib Kelish") {
                store.send(.fetchUsersTapped)
            }
        }
    }
}
```

> **Senior eslatmasi:** Har doim API call natijalarini to'g'ridan-to'g'ri Effect ichida o'zgartirmang! Effect ichidan `.send()` orqali Action qaytaring, State faqat Reducer'ning o'zida sinxron o'zgarishi kerak.

## 6. Composition (Kompozitsiya) {#composition}

TCA ning eng kuchli xususiyati — bu composition. Katta ilova bir qancha kichik va mustaqil Feature'larga (Reducer'larga) bo'linadi va ular parent tomonidan birlashtiriladi.

```swift
import SwiftUI
import ComposableArchitecture

@Reducer
struct AppFeature {
    @ObservableState
    struct State: Equatable {
        var counter = CounterFeature.State()
        var userList = UserListFeature.State()
    }
    
    enum Action {
        case counter(CounterFeature.Action)
        case userList(UserListFeature.Action)
    }
    
    var body: some ReducerOf<Self> {
        Scope(state: \.counter, action: \.action.counter) {
            CounterFeature()
        }
        Scope(state: \.userList, action: \.action.userList) {
            UserListFeature()
        }
        Reduce { state, action in
            // Parent leveldagi o'zgarishlar (agar kerak bo'lsa)
            return .none
        }
    }
}
```

## 7. Navigation TCA'da {#navigation}

TCA'da navigatsiya ham State tomonidan boshqariladi (State-driven navigation). Yangi makrolar yordamida bu juda osonlashdi.

```swift
@Reducer
struct ContactsFeature {
    @ObservableState
    struct State: Equatable {
        // Modal uchun
        @Presents var addContact: ContactDetailFeature.State?
        var contacts: [String] = []
    }
    
    enum Action {
        case addButtonTapped
        // Modal actionlari uchun
        case addContact(PresentationAction<ContactDetailFeature.Action>)
    }
    
    var body: some ReducerOf<Self> {
        Reduce { state, action in
            switch action {
            case .addButtonTapped:
                // state.addContact = ContactDetailFeature.State(name: "")
                return .none
                
            case let .addContact(.presented(.saveTapped(name))):
                state.contacts.append(name)
                state.addContact = nil // modalni yopish
                return .none
                
            case .addContact:
                return .none
            }
        }
        .ifLet(\.$addContact, action: \.addContact) {
            // ContactDetailFeature()
        }
    }
}

// View-da .sheet modifier misoli:
/*
.sheet(item: $store.scope(state: \.addContact, action: \.addContact)) { store in
    // ContactDetailView(store: store)
}
*/
```

## 8. Testing TCA {#testing}

TCA da test yozish shu qadar oson va ishonchli-ki, bu uning eng katta plyusi hisoblanadi. Siz `TestStore` ishlatasiz va action yuborib, state qanday o'zgarganini tasdiqlaysiz.

```swift
import XCTest
import ComposableArchitecture

@MainActor
final class CounterTests: XCTestCase {
    func testIncrement() async {
        let store = TestStore(
            initialState: CounterFeature.State(count: 0)
        ) {
            CounterFeature()
        }
        
        await store.send(.incrementButtonTapped) {
            $0.count = 1
        }
    }
    
    func testDecrement() async {
        let store = TestStore(
            initialState: CounterFeature.State(count: 1)
        ) {
            CounterFeature()
        }
        
        await store.send(.decrementButtonTapped) {
            $0.count = 0
        }
    }
}
```

> **Muhim:** TCA testlarida siz yuborilayotgan barcha Action'lar va State o'zgarishlarini 100% ketma-ketlikda yozishingiz shart. Aks holda test fail bo'ladi. Bu tizimda yashirin (hidden) o'zgarishlar bo'lishini oldini oladi.

## 9. TCA qachon ishlatiladi va uning kamchiliklari {#qachon-ishlatish}

**Qachon ishlatiladi?**
- Murakkab state boshqaruvi kerak bo'lgan yirik ilovalar.
- Test coverage eng muhim masala bo'lganida.
- SwiftUI-first loyihalar (ayniqsa iOS 16+ va undan yuqori uchun).
- Predictable data flow kerak bo'lgan katta jamoalarda.

**Kamchiliklari:**
- **Learning curve (O'rganish qiyinligi):** Juda ko'p yangi tushunchalar mavjud (Reducer, Effect, Dependencies).
- **Boilerplate code:** Har bir kichik element uchun State, Action, Reducer yaratish ko'p vaqt va qator kod talab qiladi.
- **UIKit integratsiyasi:** UIKit bilan ham ishlatsa bo'ladi, lekin uning to'liq salohiyati SwiftUI bilan namoyon bo'ladi.
- **Performance:** Katta struct (State) qayta yozilaverganligi sababli barcha view'lar render bo'lib ketishi mumkin (albatta, to'g'ri `Scope` va `@ObservableState` ishlatilsa buning oldini olish mumkin).

## 10. Xulosa {#xulosa}

TCA shunchaki Redux'ning SwiftUI nusxasi emas, balki asinxron operatsiyalar, dependencies inyeksiyasi va testlashni o'zida birlashtirgan to'liq va kuchli arxitekturadir. Yangi `@Reducer` va `@ObservableState` makrolari tufayli boilerplate kod sezilarli darajada kamaydi, bu esa uni endilikda nafaqat katta korporativ ilovalar, balki o'rtacha o'lchamdagi loyihalar uchun ham ajoyib tanlovga aylantiradi.

## 11. Manbalar {#manbalar}

1. [TCA GitHub Repository - Point-Free](https://github.com/pointfreeco/swift-composable-architecture)
2. [Point-Free Video Tutorials (TCA Playlist)](https://www.pointfree.co/collections/composable-architecture)
3. [TCA Documentation & Tutorials](https://pointfreeco.github.io/swift-composable-architecture/main/documentation/composablearchitecture)
