Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT] : Weather api #46

Open
wants to merge 1 commit into
base: sohyun-park
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 24 additions & 8 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import java.util.Properties

plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id ("org.jetbrains.kotlin.plugin.serialization") version "1.9.0"
id("org.jetbrains.kotlin.plugin.serialization") version "1.9.0"
id("com.google.gms.google-services")
}

Expand All @@ -15,17 +17,30 @@ android {
targetSdk = 33
versionCode = 1
versionName = "1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
debug {
buildConfigField("String", "BASE_URL", Properties().apply {
load(project.rootProject.file("local.properties").inputStream())
}["base.url"].toString())
buildConfigField("String", "SERVICE_KEY", Properties().apply {
load(project.rootProject.file("local.properties").inputStream())
}["service.key"].toString())
}
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
buildConfigField("String", "BASE_URL", Properties().apply {
load(project.rootProject.file("local.properties").inputStream())
}["base.url"].toString())
buildConfigField("String", "SERVICE_KEY", Properties().apply {
load(project.rootProject.file("local.properties").inputStream())
}["service.key"].toString())
}
}
compileOptions {
Expand All @@ -35,9 +50,10 @@ android {
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures{
buildFeatures {
dataBinding = true
viewBinding = true
buildConfig = true
}
}

Expand All @@ -54,8 +70,8 @@ dependencies {
implementation("io.coil-kt:coil-compose:2.4.0")
//viewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")
implementation ("androidx.fragment:fragment-ktx:1.6.1")
implementation ("androidx.activity:activity-ktx:1.7.2")
implementation("androidx.fragment:fragment-ktx:1.6.1")
implementation("androidx.activity:activity-ktx:1.7.2")

//jetpack navigation
implementation("androidx.navigation:navigation-fragment-ktx:2.5.3")
Expand All @@ -67,9 +83,9 @@ dependencies {
implementation("com.google.firebase:firebase-analytics-ktx")

//retrofit
implementation ("com.squareup.retrofit2:retrofit:2.9.0")
implementation ("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1")
implementation ("com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0")
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1")
implementation("com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0")

implementation(platform("com.squareup.okhttp3:okhttp-bom:4.10.0"))

Expand Down
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
android:theme="@style/Theme.GDSC"
tools:targetApi="31">
<activity
android:name=".presentation.Introduction.IntroductionActivity"
android:name=".bottomnavigation.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package com.example.gdsc.bottomnavigation

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import com.example.gdsc.databinding.FragmentFirstBinding

class FirstFragment : Fragment() {

private val viewModel by viewModels<WeatherViewModel>()

private var _binding: FragmentFirstBinding? = null
private val binding: FragmentFirstBinding
get() = requireNotNull(_binding) { " _binding이 nul이다 " }
Expand All @@ -23,10 +28,17 @@ class FirstFragment : Fragment() {

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
observe()
}

override fun onDestroy() {
_binding = null
super.onDestroy()
}

private fun observe() {
viewModel.getWeather.observe(viewLifecycleOwner) { response ->
Log.d("testtest", response.toString())
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.example.gdsc.bottomnavigation

import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.gdsc.data.ServicePool
import com.example.gdsc.data.dto.ResponseWeatherDto
import kotlinx.coroutines.launch

class WeatherViewModel : ViewModel() {
private val _getWeather: MutableLiveData<ResponseWeatherDto?> = MutableLiveData()
val getWeather: MutableLiveData<ResponseWeatherDto?> = _getWeather

init {
getWeather()
}

private fun getWeather() = viewModelScope.launch {
runCatching {
ServicePool.getWeather.getWeather()
}.fold({
_getWeather.value = it.response.body
}, {
Log.d("error", it.message.toString())
})

}
}
25 changes: 22 additions & 3 deletions app/src/main/java/com/example/gdsc/data/ServicePool.kt
Original file line number Diff line number Diff line change
@@ -1,23 +1,42 @@
package com.example.gdsc.data

import android.util.Log
import com.example.gdsc.BuildConfig.BASE_URL
import com.example.gdsc.data.api.MemberApiService
import com.example.gdsc.data.api.WeatherApiService
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import kotlinx.serialization.json.Json
import okhttp3.Interceptor
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit

object ApiFactory {
private const val BASE_URL =
"https://gdsc-4f545-default-rtdb.asia-southeast1.firebasedatabase.app/"
private fun getLogOkHttpClient(): Interceptor {
val loggingInterceptor = HttpLoggingInterceptor { message ->
Log.d("Retrofit2", "CONNECTION INFO -> $message")
}
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
return loggingInterceptor
}

private val okHttpClient = OkHttpClient.Builder()
.addInterceptor(getLogOkHttpClient())
.build()

val retrofit: Retrofit by lazy {
Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))
.build()
}

inline fun <reified T> create(): T = retrofit.create<T>(T::class.java)
}

object ServicePool {
val getMember = ApiFactory.retrofit.create(MemberApiService::class.java)
val getMember = ApiFactory.create<MemberApiService>()
val getWeather = ApiFactory.create<WeatherApiService>()
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ import retrofit2.http.GET
interface MemberApiService {
@GET("member.json")
fun getMember(): Call<List<MemberDto>>


}
35 changes: 35 additions & 0 deletions app/src/main/java/com/example/gdsc/data/api/WeatherApiService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.example.gdsc.data.api

import com.example.gdsc.BuildConfig.SERVICE_KEY
import com.example.gdsc.data.dto.BaseResponse
import com.example.gdsc.data.dto.ResponseWeatherDto
import retrofit2.http.GET
import retrofit2.http.Query

interface WeatherApiService {

companion object {
const val GET_ULTRA_SRT_NCST = "getUltraSrtNcst"
const val SERVICE_KEY_LABEL = "serviceKey"
const val NUM_OF_ROWS = "numOfRows"
const val PAGE_NO = "pageNo"
const val DATA_TYPE = "dataType"
const val BASE_DATE = "base_date"
const val BASE_TIME = "base_time"
const val NX = "nx"
const val NY = "ny"
}

@GET(GET_ULTRA_SRT_NCST)
suspend fun getWeather(
@Query(SERVICE_KEY_LABEL) serviceKey: String = SERVICE_KEY,
@Query(NUM_OF_ROWS) numOfRows: Int = 1,
@Query(PAGE_NO) pageNo: Int = 1,
@Query(DATA_TYPE) dataType: String = "JSON",
@Query(BASE_DATE) baseDate: String = "20231114",
@Query(BASE_TIME) baseTime: String = "0600",
@Query(NX) nx: Int = 55,
@Query(NY) ny: Int = 127,
): BaseResponse<ResponseWeatherDto>
}

27 changes: 27 additions & 0 deletions app/src/main/java/com/example/gdsc/data/dto/BaseResponse.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.example.gdsc.data.dto

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class BaseResponse<T>(
@SerialName("response")
val response: Response<T>
) {

@Serializable
data class Response<T>(
@SerialName("header")
val header: Header,
@SerialName("body")
val body: T? = null
)

@Serializable
data class Header(
@SerialName("resultCode")
val resultCode: String,
@SerialName("resultMsg")
val resultMsg: String
)
}
40 changes: 40 additions & 0 deletions app/src/main/java/com/example/gdsc/data/dto/ResponseWeatherDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.example.gdsc.data.dto

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class ResponseWeatherDto(
@SerialName("dataType")
val dataType: String,
@SerialName("items")
val items: Items,
@SerialName("numOfRows")
val numOfRows: Int,
@SerialName("pageNo")
val pageNo: Int,
@SerialName("totalCount")
val totalCount: Int
) {
@Serializable
data class Items(
@SerialName("item")
val item: List<Item>
) {
@Serializable
data class Item(
@SerialName("baseDate")
val baseDate: String,
@SerialName("baseTime")
val baseTime: String,
@SerialName("category")
val category: String,
@SerialName("nx")
val nx: Int,
@SerialName("ny")
val ny: Int,
@SerialName("obsrValue")
val obsrValue: String
)
}
}