[Kotlin] Unsplash API를 이용한 사진 검색기 # 1

Dev JB·2023년 4월 12일
0

Unsplash API

목록 보기
1/1
post-thumbnail

✍ Project Goal

Retrofit2 를 이용한 API 서버통신
Coroutine, Flow 를 사용해서 비동기 작업
MVVM 패턴으로 구현


📑 Development Flow

  1. Unsplash API 호출
  2. UI 작업
  3. 비지니스 서비스 구현


📷 Unsplash API 호출


👉 공식 문서에서 서비스 등록

Unsplash 개발자 페이지

로그인 후 개발자 페이지에서 Applications 을 등록할 수 있는데,
등록 후 서비스에서 사용할 Access Key 를 받을 수 있다.



👉 데이터 모델 만들기

Unsplash 공식문서

위 링크는 공식문서에서 이 프로젝트에서 사용할 'Get a random photo' 서비스 부분이다.
'Without the count parameter:' 하단의 JSON 데이터를 사용했다.

공식문서에서 긁어온 JSON 데이터는 안드로이드 스튜디오에서 위 이미지의 플러그인을 사용해서 쉽게 모델로 만들 수 있다.

data class PhotoResponseItem(
    @SerializedName("blur_hash")
    val blurHash: String?,
    val color: String?,
    @SerializedName("created_at")
    val createdAt: String?,
    @SerializedName("current_user_collections")
    val currentUserCollections: List<CurrentUserCollection>?,
    val description: String?,
    val downloads: Int?,
    val exif: Exif?,
    val height: Int?,
    val id: String?,
    @SerializedName("liked_by_user")
    val likedByUser: Boolean?,
    val likes: Int?,
    val links: Links?,
    val location: Location?,
    @SerializedName("updated_at")
    val updatedAt: String?,
    val urls: Urls?,
    val user: User?,
    val width: Int?
)

다음과 같이 직접 구현하기 복잡한 데이터를 바로 만들어준다. 굳👍



👉 Service Interface

인터페이스로 구현될 서비스 역시 공식문서에서 공식문서에서 파라미터를 참고하면 된다.

interface UnsplashApiService {
    @GET(
        "photos/random/?" +
                "client_id=" +
                "Access Key" +
                "&count=5"
    )
    fun getSearchedPhotos(
        @Query("query") query: String?
    ): Flow<List<PhotoResponseItem>>
}

위 코드는 GET 방식으로 5개의 이미지를 'getSearchedPhotos' 함수를 통해 검색어를 입력받아 요청하고 있으며 수신한 데이터를 Flow 객체로 보내고 있다.



👉 RetrofitAPI

object RetrofitApi {
    private const val BASE_URL = "https://api.unsplash.com/"

    private val unsplashApiService: UnsplashApiService by lazy {
        Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(FlowCallAdapterFactory())    // Retrofit 은 Flow 를 지원하지 않으므로 라이브러리 추가
            .client(okHttpClient)
            .build()
            .create()
    }

    fun getPhotos(query: String?): Flow<List<PhotoResponseItem>> {
        return unsplashApiService.getSearchedPhotos(query)
    }

    private val okHttpClient: OkHttpClient by lazy {
        OkHttpClient.Builder()
            .addInterceptor(HttpLoggingInterceptor().apply {
                level = HttpLoggingInterceptor.Level.BODY
            })
            .build()
    }
}

Retrofit 인스턴스는 싱글톤으로 정의했는데, 매번 인스턴스를 생성하면 네트워크 리소스를 많이 사용하게 되므로 불필요한 자원 낭비가 발생할 수 있기 때문이다.

BASE_URL을 사용하여 API 요청의 기본 URL을 설정했고, JSON 응답을 객체로 변환하기 위해 GsonConverter를 추가했다.

Flow 타입의 API 응답을 처리하기 위해 FlowCallAdapterFactory를 추가하였다.

HttpLoggingInterceptor를 API 요청 및 응답을 디버깅하기 위해 OkHttp 클라이언트를 설정했다.

이후에는 getPhotos() 함수를 정의하여 Retrofit을 사용하여 Unsplash API에서 검색어에 따른 사진 목록을 가져오도록 구현했다. 이 함수는 Flow 타입을 반환하여 비동기적으로 데이터를 가져올 수 있다.

마지막으로, Retrofit을 구성하기 위해 사용되는 OkHttp 클라이언트를 정의했는데, 이 클라이언트는 API 요청 및 응답을 로그에 기록하는 HttpLoggingInterceptor를 추가한다.



👉 사진 요청 함수 정의

class GetRandomPhotos {

    var photoItemList: List<PhotoResponseItem> = listOf()

    private val scope = CoroutineScope(Dispatchers.IO)

    suspend fun getRandomPhotosAsync(query: String? = null) = scope.async {
        RetrofitApi.getPhotos(query)
            .collect {
                Log.d("JB", "query: $query")
                photoItemList = it as MutableList<PhotoResponseItem>
            }
    }
}

위 코드는 GetRandomPhotos 클래스는 photoItemList이라는 빈 리스트를 포함하고, CoroutineScope 및 getRandomPhotosAsync() 함수를 정의한다.

getRandomPhotosAsync() 함수는 코루틴을 사용하여 API 요청을 비동기적으로 수행하도록 설계했다. 이 함수는 query 매개변수를 사용하여 검색어가 지정된 경우 해당 쿼리로 검색된 사진 목록을 가져오고, 지정되지 않은 경우 모든 사진을 가져온다.

함수 내부에서는 RetrofitApi.getPhotos(query)를 호출하여 Flow<List> 타입의 API 응답을 수신한다. 그런 다음 collect() 함수를 사용하여 해당 Flow에서 발생하는 모든 값을 수집한다.

collect() 함수는 코루틴 내에서 실행되는 Flow의 모든 값을 처리하기 위한 Kotlin 표준 라이브러리 함수이다. 이를 통해 API 응답을 photoItemList 변수에 할당하여 이후에 사용할 수 있도록 한다.

정리하자면, 이 코드는 비동기적으로 API를 호출하여 데이터를 가져올 수 있도록 설계되어 있으며, 이를 위해 코루틴과 Flow를 사용한다.


본 포스팅에서는 Unsplash API 를 호출하여 데이터를 가져오는 것까지 구현했다. 이어지는 포스팅에서는 데이터를 담을 UI를 구현하고, 데이터를 가공하여 디스플레이 하는 서비스를 구현하겠다.




읽어주셔서 감사합니다🙇‍♂️


profile
Android App Developer

0개의 댓글