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