반응형
앞선 글들에서 Retrofit + Coroutines, Kotlin Flow, OkHttp Interceptor를 활용해 네트워크 계층을 안정적으로 구성하는 방법을 다뤘습니다. 이번 글에서는 Jetpack Compose와 이 네트워크 계층을 연결하여, 실제 UI 상태를 관리하고 화면에 반영하는 방법을 소개합니다.
1. Compose에서 상태(State) 관리
Compose는 선언형 UI이므로 네트워크 응답을 받아오면 State를 갱신하여 UI를 그립니다.
@Composable
fun UserScreen(viewModel: UserViewModel) {
val uiState by viewModel.uiState.collectAsState()
when (uiState) {
is UiState.Loading -> CircularProgressIndicator()
is UiState.Success -> Text("Hello, ${(uiState as UiState.Success).user.name}")
is UiState.Error -> Text("에러 발생")
}
}
collectAsState()를 통해 Flow로 전달되는 데이터를 Compose UI에 반영합니다.
2. ViewModel과 네트워크 계층 연결
네트워크 요청은 ViewModel에서 수행하고, UI는 UiState를 구독합니다.
class UserViewModel(
private val repository: UserRepository
) : ViewModel() {
private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
val uiState: StateFlow<UiState> = _uiState
init {
fetchUser()
}
private fun fetchUser() {
viewModelScope.launch {
try {
val user = repository.getUser()
_uiState.value = UiState.Success(user)
} catch (e: Exception) {
_uiState.value = UiState.Error(e)
}
}
}
}
핵심 포인트는 UI에서 직접 네트워크를 호출하지 않고, ViewModel이 중간 계층이 되어 상태를 관리한다는 점입니다.
3. UiState 패턴 정의
네트워크 상태(로딩, 성공, 실패)를 구분하기 위해 sealed class를 활용합니다.
sealed class UiState {
object Loading : UiState()
data class Success(val user: User) : UiState()
data class Error(val exception: Throwable) : UiState()
}
이렇게 하면 Compose에서 when 구문으로 상태에 맞는 UI를 쉽게 그릴 수 있습니다.
4. 전체 흐름 정리
- ViewModel에서 네트워크 요청 실행
- 응답을 UiState로 변환
- Compose UI에서 collectAsState()로 구독
- 상태별(Loading, Success, Error)로 다른 화면 출력
5. 결론
Jetpack Compose와 네트워크 계층을 연결할 때 중요한 점은 UI는 상태만 관찰하고, 네트워크 로직은 ViewModel과 Repository에서 처리하도록 분리하는 것입니다. 이 구조를 적용하면 코드 가독성, 유지보수성, 테스트가 모두 좋아집니다.
다음 글 예고: 다음 글에서는 네트워크 계층 단위 테스트 & 통합 테스트 전략을 다뤄보겠습니다.
반응형
'개발일기' 카테고리의 다른 글
| 안드로이드 네트워크 + 로컬 캐싱 전략 (Room + Flow) (1) | 2025.09.11 |
|---|---|
| 안드로이드 에러 처리 및 UI 피드백 전략 (2) | 2025.09.10 |
| 안드로이드 앱 네트워크 최적화 (캐싱, 연결 관리, 성능 개선) (3) | 2025.09.05 |
| 네트워크 계층 단위 테스트 & 통합 테스트 전략 (2) | 2025.09.04 |
| Jetpack Compose와 네트워크 계층 연결 (상태 관리 & UI 반영) (2) | 2025.09.03 |