Hilt + Retrofit2 + Moshi + Kotlin を使って通信するまで

以前、[Dagger2 + Retrofit2 + Moshi + Kotlin を使って通信するまで](https://qiita.com/shimizu-you/items/216d875b49742f73eb86)を記事にしましたが、DaggerにHiltが追加されたので、Hiltで実装した内容を記載します。

### 導入

```gradle:/build.gradle.kts
buildscript {
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:7.0.2"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31"
        classpath "com.google.dagger:hilt-android-gradle-plugin:2.38.1"
    }
}
```

```gradle:/app/build.gradle.kts
plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-kapt'
    id 'dagger.hilt.android.plugin'
}

dependencies {
    implementation "com.google.dagger:hilt-android:2.38.1"
    kapt "com.google.dagger:hilt-android-compiler:2.38.1"
    implementation "androidx.hilt:hilt-common:1.0.0"
    kapt "androidx.hilt:hilt-compiler:1.0.0"

    implementation "com.squareup.moshi:moshi-kotlin:1.12.0"
    kapt "com.squareup.moshi:moshi-kotlin-codegen:1.12.0"

    implementation "com.squareup.retrofit2:retrofit:2.9.0"
    implementation "com.squareup.retrofit2:converter-moshi:2.9.0"
}
```

### Hiltの実装

* ```@HiltAndroidApp```を実装する。

```kotlin
@HiltAndroidApp
class MyApplication  : Application() {

    override fun onCreate() {
        super.onCreate()
    }
}
```

### Moduleの実装

```kotlin
@Module
@InstallIn(SingletonComponent::class)
class MoshiModule {

    @Provides
    @Singleton
    fun provideMoshi(): Moshi {
        return Moshi.Builder().addLast(KotlinJsonAdapterFactory()).build()
    }
}
```

```kotlin
@Module
@InstallIn(SingletonComponent::class)
class MoshiModule {

    @Provides
    @Singleton
    fun provideMoshi(): Moshi {
        return Moshi.Builder().addLast(KotlinJsonAdapterFactory()).build()
    }
}
```

```kotlin
@Module
@InstallIn(SingletonComponent::class)
class RetrofitModule {

    @Singleton
    @Provides
    fun provideRetrofit(moshi: Moshi): Retrofit {
        return Retrofit.Builder()
            .baseUrl("https://api.github.com")
            .addConverterFactory(MoshiConverterFactory.create(moshi))
            .build()
    }

    @Provides
    @Singleton
    fun provideGitHubService(retrofit: Retrofit): GitHubService = retrofit.create(GitHubService::class.java)
}
```

### Retrofit2 + Moshiの実装

例として、GitHub のユーザ情報を取得する。

```kotlin
@JsonClass(generateAdapter = true)
data class User(
    val name: String?,
    val company: String?,
    val email: String?,
    val bio: String?,
    val created_at: String?,
    val updated_at: String?
)
```

```kotlin
interface GitHubService {

    @GET("users/{username}")
    suspend fun getUser(@Path("username") user: String): Response<User>
}
```

### Repositoryの実装

* ```@Singleton```で実装して、```@Inject constructor()```で注入する。

```kotlin
@Singleton
class NetworkRepository @Inject constructor(private val gitHubService: GitHubService) {

    suspend fun getUser() :User? {
        return gitHubService.getUser("").body()
    }
}
```

### Activityの実装

* ```@AndroidEntryPoint```を実装する。

```kotlin
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    private val viewModel: MainViewModel by viewModels()

    override fun onResume() {
        super.onResume()

        viewModel.getUser()
    }
}
```

### ViewModelの実装

* ```@HiltViewModel```を実装する。

```kotlin
@HiltViewModel
class MainViewModel @Inject constructor(private val networkRepository:NetworkRepository): ViewModel() {

    fun getUser() {
        viewModelScope.launch(Dispatchers.IO) {
            val user = networkRepository.getUser()
            user?.let {

            }
        }
    }
}
```

---

ここまでで、Hilt + Retrofit2 + Moshi + Kotlin を使って通信するまでを記載しました。
Daggerでは、ComponentやViewModelなど自身で実装しないといけない箇所が何箇所かありましたが、Hiltでは、アノテーションを追加するだけで注入を実装することが可能になりました。
Daggerでは、学習コストが高いイメージでしたが、Hiltでは、楽にDIを実装出来ますので、MVVMで実装する際は、是非使ってみることをオススメします。