[Android] 스르륵 | API 연동

Hanbi·2024년 9월 28일

스르륵~

목록 보기
1/3
post-thumbnail

💸API 연동

안드로이드 네이티브 앱에서 API와의 통신을 구현하기 위해 다음 단계를 수행했습니다.

1) 의존성 추가 및 권한 설정

  • app/build.gradle 파일에 Retrofit 라이브러리 의존성을 추가
  • AndroidManifest.xml 파일에 인터넷 권한을 추가
// app/build.gradle
dependencies {
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
}
<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.INTERNET"/>

2) 데이터 클래스 정의

API 요청과 응답을 처리하기 위한 데이터 클래스를 정의합니다.

// UserSignUpRequest.kt
data class UserSignUpRequest(
    val email: String,
    val password: String,
    val name: String,
    val phoneNumber: String
)

// ResultResponseVoid.kt
data class ResultResponseVoid(
    val status: String,
    val statusCode: List<Int>,
    val message: String,
    val data: Any?
)

3) API 인터페이스 생성

Retrofit을 통해 사용할 API 메서드를 정의하는 인터페이스를 생성합니다.

// ApiService.kt
package com.example.seureureuk.network

import ...


interface ApiService {
    @PUT("participant/{participantId}")
    suspend fun confirmRequestedSettlement(@Path("participantId") participantId: Int): Response<Void>

    @GET("settlements")
    suspend fun getRequestedSettlement(): Response<RequestedSettlementResponseData>

    @GET("settlements/{settlementId}")
    suspend fun getSettlementDetail(@Path("settlementId") settlementId: Int): Response<SettlementDetailResponseData>

    @POST("settlements/{settlementId}")
    suspend fun executeSettlementProcess(@Path("settlementId") settlementId: Int): Response<SettlementCompletedResponseData>

    // id: settlementId
    @GET("settlements/{id}/participants")
    suspend fun getSettlementParticipants(@Path("id") id: Int): Response<SettlementParticipantResponseData>

    @POST("settlements/{groupId}/request")
    suspend fun addSettlement(@Path("groupId") groupId: Int, @Body request: SettlementAddRequest): Response<SettlementAddResponseData>

    @POST("groups/entrance")
    suspend fun enterGroupWithInviteCode(@Body request: GroupEntranceRequest): Response<GroupEntranceResponseData>

    @POST("groups/{groupId}/invite")
    fun createInviteCode(@Path("groupId") groupId: Int): Call<GroupInviteResponseData>

    @POST("groups")
    suspend fun createGroup(@Body request: GroupCreateRequest): Response<GroupCreateResponseData>

    @GET("groups/{groupId}/members")
    suspend fun getGroupMembers(@Path("groupId") groupId: Int): Response<GroupMemberResponseData>

    @GET("groups/{groupId}/settlements")
    suspend fun getGroupSettlements(@Path("groupId") groupId: Int): Response<GroupSettlementResponseData>

    @GET("groups")
    fun getAllGroups(): Call<GroupInfoResponseList>

    @POST("users/register")
    fun signUpUser(@Body request: UserSignUpRequest): Call<ResultResponseVoid>

    @POST("users/auth/login")
    fun loginUser(@Body request: UserLoginRequest): Call<ResultResponseUserLoginResponse>

    @POST("accounts/register")
    fun registerAccount(@Body request: AccountRegisterRequest): Call<ResultResponseVoid>

    @GET("points")
    fun getPointInfo(): Call<ResultResponsePointInfoResponse>

    @GET("accounts")
    fun getAccounts(): Call<ResultResponseListAccountResponse>

    @POST("points")
    fun convertPoints(@Body request: PointConversionRequest): Call<ResultResponsePointConversionResponse>

    @DELETE("accounts/{accountId}/delete")
    fun deleteAccount(@Path("accountId") accountId: Long): Call<ResultResponseVoid>

    @POST("points/exchange")
    fun convertPointsExchange(@Body request: PointConversionRequest): Call<ResultResponsePointConversionResponse>

    @GET("users")
    fun getUserMyPageInfo(): Call<ResultResponseUserMyPageResponse>

}

4) Retrofit 인스턴스 설정

Retrofit 인스턴스를 생성하여 API 서비스와 연결합니다.

// RetrofitInstance.kt
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

object RetrofitInstance {
    private const val BASE_URL = "http://172.191.5.168/api/"

    val api: ApiService by lazy {
        Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(ApiService::class.java)
    }
}

5) Activity에서 API 호출

// MyPageActivity.kt
package com.example.seureureuk

import ...

class MyPageActivity : AppCompatActivity() {

    private lateinit var nameTextView: TextView
    private lateinit var balanceTextView: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_my_page)

        nameTextView = findViewById(R.id.user_name)
        balanceTextView = findViewById(R.id.balance_amount)

        loadUserInfo()
        loadUserPoints()
    }

    //유저 정보 불러오기 위해 API 호출
    private fun loadUserInfo() {
        val apiService = RetrofitInstance.api
        apiService.getUserMyPageInfo().enqueue(object : Callback<ResultResponseUserMyPageResponse> {
            override fun onResponse(call: Call<ResultResponseUserMyPageResponse>, response: Response<ResultResponseUserMyPageResponse>) {
                if (response.isSuccessful) {
                    val userInfo = response.body()?.data
                    if (userInfo != null) {
                        nameTextView.text = userInfo.name
                        Log.d("MyPageActivity","$userInfo.name")
                    } else {
                        Toast.makeText(this@MyPageActivity, "사용자 정보를 불러올 수 없습니다.", Toast.LENGTH_SHORT).show()
                    }
                } else {
                    Log.e("MyPageActivity", "Failed to load user info: ${response.errorBody()?.string()}")
                }
            }

            override fun onFailure(call: Call<ResultResponseUserMyPageResponse>, t: Throwable) {
                Log.e("MyPageActivity", "Error: ${t.message}")
            }
        })
    }

    //포인트 정보 불러오기 위해 API 호출
    private fun loadUserPoints() {
        val apiService = RetrofitInstance.api
        apiService.getPointInfo().enqueue(object : Callback<ResultResponsePointInfoResponse> {
            override fun onResponse(call: Call<ResultResponsePointInfoResponse>, response: Response<ResultResponsePointInfoResponse>) {
                if (response.isSuccessful) {
                    val pointInfo = response.body()?.data
                    if (pointInfo != null) {
                        val pointValue = pointInfo.point
                        val formattedPoint = NumberFormat.getNumberInstance(Locale.KOREA).format(pointValue) + "원"
                        balanceTextView.text = formattedPoint
                        Log.d("MyPageActivity", "$pointInfo")
                    } else {
                        Toast.makeText(this@MyPageActivity, "포인트 정보를 불러올 수 없습니다.", Toast.LENGTH_SHORT).show()
                    }
                } else {
                    val errorBody = response.errorBody()?.string() ?: "Unknown error"
                    Log.e("MyPageActivity", "Failed to load points info: $errorBody")
                }
            }

            override fun onFailure(call: Call<ResultResponsePointInfoResponse>, t: Throwable) {
                Log.e("MyPageActivity", "Network error: ${t.message}")
            }
        })
    }
}

초기 세팅 후, !! 추가로 API 연동할 때는 !!

1. Request, Response 데이터 클래스 정의 ⚠️ Response에서 statusCode Int로 하기 ⚠️
2. APiService에 API 호출 추가
3. Retrofit 인스턴스 업데이트
4. Activity에서 API 호출

profile
👩🏻‍💻

0개의 댓글