개발

카카오 API 이미지 검색 삽질 기록

kks950115 2024. 1. 30. 21:44
728x90

api로 이미지 검색 결과를 받는데 자꾸 결과에 널이 뜬다....

이상하다. 뭐가 문제지? 했는데 interface에 반환타입 KakaoImg가 문제였다.

KakaoImg클래스와 APIResponse 클래스는 구조는 같다.

다만 KakaoImg 가  APIResponse 를 한번 더 감싼 형태라서 정보를  담아내지 못헀던 것이다.

반환타입을 APIResponse으로 바꾸니 바로 되었다. 

 

 

아래는 그 당시 코드.

interface

interface KakaoImageAPI {
    @GET("v2/search/image")
    suspend fun getPost(
        @Header("Authorization") apiKey : String,
        @Query("query") searchKeyword: String
    ) : KakaoImg 
}

constants.kt

object Constants {
    const val KAKAO_AUTHKEY = "KakaoAK 개인용 키"

}
data class Post(
    @SerializedName("thumbnail_url")
    val img : String,
    @SerializedName("display_sitename")
    val title : String,
    @SerializedName("datetime")
    val time : String
)

data class MetaData(
    @SerializedName("total_count")
    val totalCount: Int,
    @SerializedName("pageable_count")
    val pageableCount : Int,
    @SerializedName("is_end")
    val isEnd:Boolean
)

data class APIResponse(
    @SerializedName("meta")
    val metaData : MetaData,
    val documents : MutableList<Post>
)

data class KakaoImg (val imgResponse: APIResponse)

 

networkclient.kt


object NetWorkClient {
    private const val BSEE_URL = "https://dapi.kakao.com/"

    private fun createOkHttpClient(): OkHttpClient{
        val interceptor = HttpLoggingInterceptor()

        if(BuildConfig.DEBUG){
            interceptor.level = HttpLoggingInterceptor.Level.BODY
        } else {
            interceptor.level = HttpLoggingInterceptor.Level.NONE
        }
        return OkHttpClient.Builder()
            .connectTimeout(20,TimeUnit.SECONDS)
            .readTimeout(20,TimeUnit.SECONDS)
            .writeTimeout(20,TimeUnit.SECONDS)
            .addNetworkInterceptor(interceptor)
            .build()
    }

    private val imageRetrofit = Retrofit.Builder()
        .baseUrl(BSEE_URL)
        .addConverterFactory(GsonConverterFactory.create()).client(
            createOkHttpClient()
        ).build()

    val imageNetwork : KakaoImageAPI= imageRetrofit.create(KakaoImageAPI::class.java)
}

 

searchFragment.kt

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



    binding.btnSearch.setOnClickListener {
        val keyword = binding.etSearch.text.toString()
        loadImage(keyword)

    }

}

private fun loadImage(str:String)  {
    CoroutineScope(Dispatchers.Main).launch {

        val responseData = getPosts(str)
        posts = responseData.APIResponse.documents
        val imgAdapter = ImageAdapter(posts)
        binding.rvImgItem.adapter =  imgAdapter
        binding.rvImgItem.layoutManager = GridLayoutManager(context,2)
        binding.rvImgItem.hasFixedSize()
    }
}

private suspend fun getPosts(str:String) = withContext(Dispatchers.IO){
    NetWorkClient.imageNetwork.getPost(Constants.KAKAO_AUTHKEY,str)
}

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp"
    tools:context=".SearchFragment">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/constraintLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#dddddd"
        app:layout_constraintTop_toTopOf="parent">

        <EditText
            android:id="@+id/et_search"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="10dp"
            android:layout_marginTop="10dp"
            android:layout_marginEnd="10dp"
            android:layout_marginBottom="10dp"
            android:background="@color/white"
            android:padding="10dp"
            android:text="아이유"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/btn_search"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <Button
            android:id="@+id/btn_search"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:layout_marginEnd="10dp"
            android:layout_marginBottom="10dp"
            android:text="검색"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </androidx.constraintlayout.widget.ConstraintLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_imgItem"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/constraintLayout" />

</androidx.constraintlayout.widget.ConstraintLayout>

rv_item.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="5dp">

    <ImageView
        android:id="@+id/iv_like"
        android:layout_width="45dp"
        android:layout_height="45dp"
        android:layout_marginTop="10dp"
        android:layout_marginEnd="10dp"
        android:elevation="2dp"
        android:visibility="invisible"
        android:src="@drawable/heart_empty"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <ImageView
        android:id="@+id/iv_img"
        android:layout_width="200dp"
        android:layout_height="200dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:ellipsize="end"
        android:maxLines="2"
        android:text="이름이름이름이름이이름이름이름이름이름름이름이름이름이름이름이름"
        android:textSize="16sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/iv_img" />

    <TextView
        android:id="@+id/tv_date"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="날짜"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_title" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

 

728x90
반응형