LAB 6 — Networking with Retrofit & Coil ========================================= Mobile Application Development | SUZA | Semester II 2025/2026 OBJECTIVES ---------- - Call a REST API using Retrofit + coroutines - Deserialize JSON into Kotlin data classes - Load remote images with Coil - Model UI state as Loading / Success / Error PERMISSIONS ----------- In AndroidManifest.xml add: DEPENDENCIES ------------ implementation("com.squareup.retrofit2:retrofit:2.9.0") implementation("com.squareup.retrofit2:converter-kotlinx-serialization:2.9.0") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0") implementation("io.coil-kt:coil-compose:2.5.0") PART A — Dog Breed Explorer (Dog CEO API) ----------------------------------------- Public API — no key needed: https://dog.ceo/dog-api/documentation/ 1. Fetch 20 random dog images: GET https://dog.ceo/api/breeds/image/random/20 Response: { "message": [url1, url2, ...], "status": "success" } 2. Define: @Serializable data class DogResponse(val message: List, val status: String) 3. Retrofit interface: interface DogApi { @GET("api/breeds/image/random/20") suspend fun getImages(): DogResponse } 4. UI state: sealed interface DogUiState { object Loading : DogUiState data class Success(val urls: List) : DogUiState data class Error(val message: String) : DogUiState } 5. Screen: - Top: TopAppBar "Dog Explorer", refresh icon - On loading: CircularProgressIndicator - On success: LazyVerticalGrid of AsyncImage tiles - On error: centered message + Retry button 6. Implement pull-to-refresh using PullToRefreshBox (Material 3). PART B — Country Facts ---------------------- Use https://restcountries.com/v3.1/all (public, no key) 1. Parse fields: name.common, capital, region, population, flags.png Use @SerialName when needed. 2. Show a LazyColumn; tap item → DetailScreen with full info + flag. 3. Add a search TextField that filters locally (use derivedStateOf). STRETCH GOALS (optional) ------------------------ - Add an OkHttp cache so the list works offline after the first load. - Show a snackbar when the network returns an error. - Persist favourites to Room so they survive app restarts. ERROR HANDLING CHECKLIST ------------------------ [ ] Catch IOException -> "Check your internet connection" [ ] Catch HttpException -> "Server error " [ ] Catch generic -> "Unexpected error: " [ ] Retry button actually retries (calls load() again) [ ] Show proper empty state if list is empty DELIVERABLES ------------ - Project "ApiExplorer" on GitHub as "mad-lab06" - Screenshots: loading, success, error, detail, search - NOTES.md: 200 words on why we use suspend + Flow instead of AsyncTask