# Networking & REST API — To'liq Darslik

## Mundarija
1. [Nega Networking kerak? (Motivatsiya)](#motivatsiya)
2. [HTTP Asoslari](#http-asoslari)
3. [URLSession Asoslari](#urlsession-asoslari)
4. [Codable — JSON Parsing](#codable)
5. [Async/Await bilan Networking](#async-await)
6. [Error Handling (Xatolarni boshqarish)](#error-handling)
7. [Pagination (Sahifaviy yuklash)](#pagination)
8. [Image Loading & Caching](#image-loading)
9. [Network Layer Arxitekturasi](#network-architecture)
10. [Interceptors & Middleware](#interceptors)
11. [URLSession vs Alamofire](#urlsession-vs-alamofire)
12. [Xulosa va keyingi qadamlar](#xulosa)

---

## 1. Nega Networking kerak? (Motivatsiya) {#motivatsiya}

Deyarli har bir zamonaviy iOS ilovasi internetga ulangan bo'lishi kerak. Nega?
- **Ma'lumotlar almashinuvi:** Foydalanuvchi profilini yuklash, postlar ko'rish, xabar yuborish.
- **Server-side logic:** Og'ir hisob-kitoblar yoki sun'iy intellekt amallarini serverda bajarish.
- **Real-time yangilanishlar:** Ob-havo, valyuta kurslari yoki yangiliklarni doimiy ravishda yangilab turish.

Networking bo'lmasaydi, ilovalar shunchaki "o'lik" ma'lumotlar ombori bo'lib qolardi.

---

## 2. HTTP Asoslari {#http-asoslari}

Server bilan muloqot qilishning asosiy tili — **HTTP (HyperText Transfer Protocol)**.

### Metodlar:
- **GET:** Ma'lumotni o'qish (masalan, feed'ni ko'rish).
- **POST:** Yangi ma'lumot yaratish (masalan, yangi akkaunt ochish).
- **PUT:** Bor ma'lumotni to'liq yangilash.
- **PATCH:** Ma'lumotning bir qismini o'zgartirish.
- **DELETE:** Ma'lumotni o'chirish.

### Status Code'lar:
- **200-299:** Muvaffaqiyat (Success).
- **400-499:** Mijoz xatosi (Client Error — masalan, 404 Not Found).
- **500-599:** Server xatosi (Server Error).

---

## 3. URLSession Asoslari {#urlsession-asoslari}

Apple'ning networking uchun asosiy quroli — `URLSession`.

```swift
// Eng oddiy GET so'rov
func fetchSimpleData() {
    guard let url = URL(string: "https://api.example.com/data") else { return }
    
    let task = URLSession.shared.dataTask(with: url) { data, response, error in
        if let error = error {
            print("Xato: \(error)")
            return
        }
        
        if let data = data {
            print("Ma'lumot keldi: \(data.count) bytes")
        }
    }
    task.resume() // Bu buyruq so'rovni boshlaydi!
}
```

---

## 4. Codable — JSON Parsing {#codable}

Serverdan ma'lumotlar ko'pincha **JSON** formatida keladi. Ularni Swift obyektlariga o'tkazish uchun `Codable` ishlatiladi.

```swift
struct User: Codable {
    let id: Int
    let name: String
    let email: String
    
    // Agar JSON dagi nom boshqacha bo'lsa:
    enum CodingKeys: String, CodingKey {
        case id
        case name = "full_name"
        case email
    }
}

// Dekodlash (JSON -> Object)
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase // optional
let user = try decoder.decode(User.self, from: jsonData)
```

---

## 5. Async/Await bilan Networking {#async-await}

iOS 15 dan boshlab networking ancha toza ko'rinishga keldi.

```swift
func fetchUsers() async throws -> [User] {
    let url = URL(string: "https://api.example.com/users")!
    
    // Async so'rov
    let (data, response) = try await URLSession.shared.data(from: url)
    
    // Status kodni tekshirish
    guard let httpResponse = response as? HTTPURLResponse,
          (200...299).contains(httpResponse.statusCode) else {
        throw NetworkError.invalidResponse
    }
    
    return try JSONDecoder().decode([User].self, from: data)
}
```

---

## 6. Error Handling (Xatolarni boshqarish) {#error-handling}

Professional ilovada xatolarni foydalanuvchiga tushunarli qilib ko'rsatish kerak.

```swift
enum NetworkError: Error, LocalizedError {
    case invalidURL
    case invalidResponse
    case decodingError
    case serverError(String)
    
    var errorDescription: String? {
        switch self {
        case .invalidURL: return "URL noto'g'ri."
        case .invalidResponse: return "Serverdan xato javob keldi."
        case .decodingError: return "Ma'lumotni o'qishda xato."
        case .serverError(let msg): return "Server xatosi: \(msg)"
        }
    }
}
```

---

## 7. Pagination (Sahifaviy yuklash) {#pagination}

Minglab postlarni birdaniga yuklash xotirani to'ldirib yuboradi. Shuning uchun sahifalab yuklanadi.

1. **Offset-based:** `limit=20&offset=0`, keyin `offset=20`...
2. **Cursor-based:** `next_cursor=abc123`. Xavfsizroq va tezroq.

---

## 8. Image Loading & Caching {#image-loading}

Internetdan rasmlarni yuklash og'ir amal. Ularni keshlab qo'yish shart.

```swift
// SwiftUI AsyncImage
AsyncImage(url: URL(string: "https://example.com/img.jpg")) { image in
    image.resizable().scaledToFit()
} placeholder: {
    ProgressView()
}
```

Ilg'or loyihalarda **NSCache** yoki **SDWebImage / Kingfisher** ishlatish tavsiya etiladi.

---

## 9. Network Layer Arxitekturasi {#network-architecture}

Kodni har doim modullarga bo'ling. Protocol-based yondashuv test qilishni osonlashtiradi.

```swift
protocol APIClient {
    func request<T: Decodable>(_ endpoint: Endpoint) async throws -> T
}

enum Endpoint {
    case getUsers
    case getPost(id: Int)
    
    var path: String {
        switch self {
        case .getUsers: return "/users"
        case .getPost(let id): return "/posts/\(id)"
        }
    }
}
```

---

## 10. Interceptors & Middleware {#interceptors}

Har bir so'rovga "Auth Token" qo'shish yoki 401 (Unauthorized) bo'lganda tokenni yangilash (refresh token) uchun ishlatiladi.

---

## 11. URLSession vs Alamofire {#urlsession-vs-alamofire}

| Xususiyat | URLSession | Alamofire |
|-----------|:---:|:---:|
| **Dependency** | Native (Apple) | External (Library) |
| **Retry Logic** | Manual | Built-in |
| **File Upload** | Murakkabroq | Juda oson |
| **Logger** | Manual | Ajoyib (NetworkLogger) |

**Tavsiya:** Kichik va o'rta loyihalar uchun Native `URLSession` kuchi yetarli. Murakkab fayl yuklamalari bo'lsa `Alamofire` yaxshi tanlov.

---

## 12. Xulosa va keyingi qadamlar {#xulosa}

Siz hozirgina zamonaviy iOS networking asoslarini o'rgandingiz. Keyingi qadamlar:
1. Birorta bepul API (masalan, JSONPlaceholder) bilan kichik loyiha qilib ko'ring.
2. `async/await` va `Codable` dan foydalaning.
3. Xatolarni chiroyli tarzda `Alert` yoki `Toast` orqali ko'rsatishni mashq qiling.

Muvaffaqiyatlar! 🚀
