Kotlin + API 캐싱 : 날씨 정보 앱

2025. 5. 15. 13:24카테고리 없음

날씨 정보 앱 만들기 (Kotlin + API 캐싱)

🎯 목표

  • 현재 날씨 정보를 보여주는 앱 만들기
  • 외부 API 호출 + 로컬 캐싱 기능 구현
  • Kotlin 기본 문법 & API 처리 & 캐싱 로직 학습

 

 

🗂️ Step 1. 준비 작업

  1. API 선택
  2. 프로젝트 생성
    • Android Studio → New Project (Empty Activity)
    • Language: Kotlin
    • 이름: WeatherApp

 

 

🛠️ Step 2. API 호출 코드 작성

  • Retrofit 라이브러리 추가
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
  • API 인터페이스 정의
interface WeatherApiService {
    @GET("weather")
    suspend fun getCurrentWeather(
        @Query("q") city: String,
        @Query("appid") apiKey: String,
        @Query("units") units: String = "metric"
    ): Response<WeatherResponse>
}
  • Retrofit 객체 생성
object RetrofitClient {
    private const val BASE_URL = "https://api.openweathermap.org/data/2.5/"

    val instance: WeatherApiService by lazy {
        val retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        retrofit.create(WeatherApiService::class.java)
    }
}

 

 

🧠 Step 3. 캐싱 로직 구현 (SharedPreferences)

  • 데이터 저장 함수
fun cacheWeatherData(context: Context, data: String) {
    val sharedPref = context.getSharedPreferences("weather_cache", Context.MODE_PRIVATE)
    sharedPref.edit().putString("cached_data", data).apply()
}
  • 데이터 불러오기 함수
fun getCachedWeatherData(context: Context): String? {
    val sharedPref = context.getSharedPreferences("weather_cache", Context.MODE_PRIVATE)
    return sharedPref.getString("cached_data", null)
}

 

 

🖼️ Step 4. UI 구성

  • EditText: 도시 이름 입력
  • Button: 조회 버튼
  • TextView: 날씨 결과 표시

→ activity_main.xml에 배치

 

 

🔄 Step 5. API 호출 + 캐싱 연결

  1. 조회 버튼 클릭 시:
    • API 호출 (Coroutine 사용)
    • 성공 → UI 표시 + 캐싱 저장
    • 실패 → 캐시 데이터 로드해서 표시
  2. 예시 코드
lifecycleScope.launch {
    try {
        val response = RetrofitClient.instance.getCurrentWeather(city, "YOUR_API_KEY")
        if (response.isSuccessful) {
            val weatherInfo = response.body()?.main?.temp.toString() + "°C"
            textViewResult.text = weatherInfo
            cacheWeatherData(this@MainActivity, weatherInfo)
        } else {
            textViewResult.text = "API Error: ${response.code()}"
        }
    } catch (e: Exception) {
        val cached = getCachedWeatherData(this@MainActivity)
        textViewResult.text = cached ?: "데이터 불러오기 실패"
    }
}

 

 

🏁 Step 6. 테스트 & 마무리

  • 정상 조회 → 캐시 저장 확인
  • 비행기 모드 (API 호출 실패 시 캐시 표시)
  • 도시 이름 바꿔서 테스트