KotlinでWeb APIを叩いてみる: Retrofit + RxJava + Gson

やること：
1. Retrofit, RxJava, Gsonのdependenciesを追記
2. manifestにpermissionを追記
3. データクラスとクライエントインタフェースを書く
4. MainActivityでサービスにアクセス

-- 


build.gradle (Module:app)

```Kotlin
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
    def rv = '2.6.0'
    implementation "com.squareup.retrofit2:retrofit:$rv"
    implementation "com.squareup.retrofit2:converter-gson:$rv"
    implementation "com.squareup.retrofit2:adapter-rxjava2:$rv"
    implementation 'com.squareup.okhttp3:okhttp:4.0.0-RC1'
```

AndroidManifest.xml

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

クライエントのインターフェース (Client.kt とか Service.kt とか)

```Kotlin
package com.example.<app name>

import io.reactivex.Observable
import retrofit2.http.GET

interface Client {
    @GET("api")
    fun getUser(): Observable<RandomUser>
}
```

データのクラス (Model.ktとか）
- APIのresponseのJSONをクラスに落しこんでく感じ
- 必要なデータだけとってきてもok
- List<オブジェクト>も適宜使うのがポイント？

```Kotlin
package com.example.randomuserdemo

data class RandomUser(var results: List<Result>,
                      var info: Info)

data class Info (var see: String)

data class Result (var gender: String,
                    var email: String)
```
この例でモデルにしたのは https://randomuser.me のやつ

```JSON
{
  "results": [
    {
      "gender": "male",
      "name": {
        "title": "mr",
        "first": "rolf",
        "last": "hegdal"
      },
      "location": {
        "street": "ljan terrasse 346",
        "city": "vear",
        "state": "rogaland",
        "postcode": "3095",
        "coordinates": {
          "latitude": "54.8646",
          "longitude": "-97.3136"
        },
        "timezone": {
          "offset": "-10:00",
          "description": "Hawaii"
        }
      },
      "email": "rolf.hegdal@example.com",
      "login": {
        "uuid": "c4168eac-84b8-46ea-b735-c9da9bfb97fd",
        "username": "bluefrog786",
        "password": "ingrid",
        "salt": "GtRFz4NE",
        "md5": "5c581c5748fc8c35bd7f16eac9efbb55",
        "sha1": "c3feb8887abed9ec1561b9aa2c9f58de21d1d3d9",
        "sha256": "684c478a98b43f1ef1703b35b8bbf61b27dbc93d52acd515e141e97e04447712"
      },
      "dob": {
        "date": "1975-11-12T06:34:44Z",
        "age": 42
      },
      "registered": {
        "date": "2015-11-04T22:09:36Z",
        "age": 2
      },
      "phone": "66976498",
      "cell": "40652479",
      "id": {
        "name": "FN",
        "value": "12117533881"
      },
      "picture": {
        "large": "https://randomuser.me/api/portraits/men/65.jpg",
        "medium": "https://randomuser.me/api/portraits/med/men/65.jpg",
        "thumbnail": "https://randomuser.me/api/portraits/thumb/men/65.jpg"
      },
      "nat": "NO"
    }
  ],
  "info": {
    "seed": "2da87e9305069f1d",
    "results": 1,
    "page": 1,
    "version": "1.2"
  }
}
```

MainActivityでAPIを叩く

```Kotlin
package com.example.randomuserdemo

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.google.gson.FieldNamingPolicy
import com.google.gson.GsonBuilder
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        val gson = GsonBuilder()
            .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
            .create() // 

        val retrofit = Retrofit.Builder()
            .baseUrl("https://randomuser.me")
            .addConverterFactory(GsonConverterFactory.create(gson))
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()


        val client = retrofit.create(Client::class.java)
        client.getUser()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                Log.d("suyaa", it.toString())
            }, {
                Log.d("suyaa", it.toString())
            })
    }
}
```