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

임혁_7주차_과제 #79

Open
201810988 opened this issue Jun 2, 2021 · 0 comments
Open

임혁_7주차_과제 #79

201810988 opened this issue Jun 2, 2021 · 0 comments

Comments

@201810988
Copy link

7주차

Retrofit, OkHttp 가 뭔가요?

Retrofit은 Java 와 Android를 위한 REST client 입니다. 이 library는 JSON 또는 다른 구조적인 data를 좀더 쉽게 REST 기반으로 얻고 업로드 할 수있습니다.

Retrofit에서는 data의 직렬화에 사용되는 converter를 설정할 수있어, 예를 들어 JSON과 objects 사이의 serialize, deserialize를 GSON을 이용하기도 합니다. XML 또는 다른 protocols을 처리하기위한 custom 한 converters 또란 추가 할 수 있습니다.

Http 요청을 만들기 위해서 Retrofit은 OkHttp library를 사용합니다. OkHttp는 low-level의 네트워크 operation, caching, requests, responses 를 담당하는 pure한 HTTP/SPDY client 입니다. 반면에 Retrofit은 OkHttp 위의 high-level의 REST 추상 구현 입니다.

Retrofit

GSON

Practice

첫 번째로 인터넷 허락을 해줍니다.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.baruckis.mycryptocoins">

    <uses-permission android:name="android.permission.INTERNET" />
    ...
</manifest>

두 번째로 사용할 라이브러리를 추가해줍니다

dependencies {
		// Retrofit 과 OkHttp(의존성이 Retrofit에 ship 되어 있다). 
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
		// GSON
    implementation 'com.google.code.gson:gson:2.8.7'
	...
}

Retrofit interface 를 제작한다. 그리고 요청을 받은 data class

interface ApiService {
    // @GET 어노테이션이 이 요청이 get type 임을 retrofit 에게말한다.
    // 파라미터가 이 요청의 경로가 어딘지 baseURL + "GET 파라미터" + "Query 파라미터"
    @GET("v1/cryptocurrency/listings/latest")
    fun Cryptocurrencies(@Query("convert") currency: String): Call<CryptocurrenciesLatest>
    // 예 : https://sandbox-api.coinmarketcap.com/v1/cryptocurrency/listings/latest?convert=KRW.
    //     baseURL                               path                             query
}

/**
 * 서버로 부터 온 response 를 다루는 data class
 */
data class CryptocurrenciesLatest(
    val status: Status,
    val data: List<Data>
) {
	... 생략 ...
}

request 요청에 interceptor 를 이용해 header를 추가하여 인증을 하자!

// https://pro.coinmarketcap.com/
class AuthenticationInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val newRequest = chain.request().newBuilder()
            .addHeader("X-CMC_PRO_API_KEY", "88e93310-8005-4511-a370-5aa4c9f550e3")
            .build()
        return chain.proceed(newRequest)
    }
}

마지막으로 Activity를 작성합니다!!

class MainActivity : AppCompatActivity() {

    private lateinit var listView: ListView
    private lateinit var listAdapter: AddSearchListAdapter

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

        listView = findViewById(R.id.listview_activity_add_search)
        setupList()

        setupRetrofitTemporarily()
    }

    private fun setupRetrofitTemporarily() {
        // 인증을 위해 interceptor 를 이용하고 이를 위해선 custom 한 okHttp client 가 필요합니다.
        val builder = OkHttpClient.Builder()
        builder.interceptors().add(AuthenticationInterceptor())
        val client = builder.build()

        val api = Retrofit.Builder()
            .baseUrl("https://sandbox-api.coinmarketcap.com/")
            .addConverterFactory(GsonConverterFactory.create()) // GSON converter 를 사용해 JSON 을 POJO 객체로 매핑
            .client(client) // 여기서 방금 만든 custom OkHttp client 를 설정 해줍니다.
            .build().create(ApiService::class.java) // 우리가 만든 interface 를 통해 API를 만든다.

        val adapterData: MutableList<Cryptocurrency> = ArrayList()

        val currentFiatCurrencyCode = "KRW"

        // 비동기적
        val call = api.getAllCrytocurrencies("KRW")
        val result = call.enqueue(object : Callback<CryptocurrenciesLatest> {

            override fun onResponse(
                call: Call<CryptocurrenciesLatest>,
                response: Response<CryptocurrenciesLatest>
            ) {
                // response가 성공적인 지 확인합니다. 즉, 요청이 성공적으로
                // received, understood, accepted and returned code in range [200..300).
                if (response.isSuccessful) {
                    Log.d("MainActivity call", "${response.body()}")
                    Toast.makeText(this@MainActivity, "Call Ok", Toast.LENGTH_SHORT).show()
                    val cryptocurrenciesLatest: CryptocurrenciesLatest? = response.body()
                    cryptocurrenciesLatest!!.data.forEach {
                        val cryptocurrency = Cryptocurrency(
                            it.name, it.cmcRank.toShort(),
                            0.0, it.symbol, currentFiatCurrencyCode, it.quote.currency.price,
                            0.0, it.quote.currency.percentChange1h,
                            it.quote.currency.percentChange7d, it.quote.currency.percentChange24h,
                            0.0
                        )
                        adapterData.add(cryptocurrency)
                    }
                    listAdapter.setData(adapterData)
                } else {
                    Snackbar.make(
                        findViewById(android.R.id.content),
                        "Call error with HTTP status code ${response.code()}!",
                        Snackbar.LENGTH_INDEFINITE
                    ).show()
                }
            }

            // server 에서 무언가 잘 못 되더라고 항상 response를 받도록 설계됨.
            override fun onFailure(call: Call<CryptocurrenciesLatest>, t: Throwable) {
                Snackbar.make(
                    findViewById(android.R.id.content),
                    "요청 실패! ${t.localizedMessage}",
                    Snackbar.LENGTH_INDEFINITE
                ).show()
            }
        })

    }

    private fun setupList() {
        listAdapter = AddSearchListAdapter(this)
        listView.adapter = listAdapter
    }

}

자세한 코드는 project 링크를 참조하세요!

Untitled

실행결과!

OKHttp

OkHttp는 HTTP client 입니다.

  • HTTP/2 지원
  • Connection pooling reduces request latency
  • Transparent GZIP shrinks download sizes.
  • Response caching avoids the network completely for repeat requests.

간단한 call

import okhttp3.OkHttpClient
import okhttp3.Request
fun main(args: Array<String>) {
    val url = "https://github.com/lookiesmu/LOOKIE_FRONT_2021"
    val client = OkHttpClient()
    val response = client.newCall(
        Request.Builder()
            .url(url)
            .build()
    ).execute()
    println(response.body?.string()) // body의 html 출력
}

Untitled 1

7.pdf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant