[compose multiplatform 中級チュートリアル6]supabaseからデータを読む

# はじめに
[前回](https://qiita.com/shunk0616/private/64f9319d1067a7c6962d)はsupabaseとの接続の準備のために、アーキテクチャを整えたり、DIを導入したり、インターフェースを作成したりしました。
今回は実際にsupabaseとアプリを接続して、データを表示するところまでやっていきましょう。

# supabaseのデータベースからデータを取得する処理を実装
まずは前回作った、TaskApi.ktを編集して、supabaseのデータベースからデータを取得する処理を実装します。

## インターフェースを作成する
TaskApi.ktのsealed interface MessageApiを以下のように修正します。
```kotlin:TaskApi.kt
sealed interface TaskApi {
    suspend fun fetchAll(): List<Task>
}
```

## 実装する
次にTaskApiImplを以下のように修正します。
```kotlin:TaskApi.kt
internal class TaskApiImpl(
    private val client: SupabaseClient
) : TaskApi {
    private val table = client.postgrest["tasks"]
    override suspend fun fetchAll(): List<Task> {
        return table.select().decodeList()
    }
}
```


# 呼び出してみる
使えるかわからないけれど、一旦データを取得する処理を実装したので、使ってみましょう。
流れとしては、ListScreenModel内部で、データ取得処理を呼び出して、データを取得したら、ListScreenModelのtasksにデータをセットして、ListScreenに表示するようにします。
ui/List/ListScreenModel.ktを以下のように修正します。
```kotlin:ListScreenModel.kt
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import cafe.adriel.voyager.core.model.ScreenModel
import cafe.adriel.voyager.core.model.coroutineScope
import co.touchlab.kermit.Logger
import kotlinx.coroutines.launch
import org.company.saikyotodo.net.Task
import org.company.saikyotodo.net.TaskApi

class ListScreenModel(
    private val taskApi: TaskApi // TaskApiのインスタンスを注入。API呼び出し用
) : ScreenModel { // VoyagerのScreenModelを継承。画面固有のロジックやデータを保持

    private val _tasks = mutableStateOf<List<Task>>(emptyList()) // タスクのリストを保持する内部状態
    val tasks: State<List<Task>> = _tasks // _tasksの公開状態。UIからアクセスされる

    init {
        coroutineScope.launch { // コルーチンを開始。非同期処理を行う
            kotlin.runCatching {
                taskApi.fetchAll() // APIを呼び出して全タスクを取得
            }.onSuccess {
                _tasks.value = it // 取得成功時、タスクリストを更新
            }.onFailure {
                Logger.e(it) { "Error while fetching tasks" } // エラー発生時、ログに記録
            }
        }
    }
}
```

次にListScreen内で、ListScreenModelを呼び出して、tasksを表示するようにします。
ui/List/ListScreen.ktを以下のように修正します。
```kotlin:ListScreen.kt
import cafe.adriel.voyager.core.screen.Screen
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import org.company.saikyotodo.di.getScreenModel
import org.company.saikyotodo.ui.Common.Composable.Category

class ListScreen(): Screen { // VoyagerのScreenインターフェースを実装。画面のコンポーザブルを提供
    @Composable
    override fun Content() {
        val screenModel = getScreenModel<ListScreenModel>() // ListScreenModelを取得
        var tasks = screenModel.tasks.value // タスクのリストをStateから取得
        val categories = listOf("バックログ", "対応中", "完了") // カテゴリのリストを定義

        Column(modifier = Modifier.padding(20.dp).fillMaxSize()) { // 縦に要素を配置するColumn
            // 各カテゴリに対して、Categoryコンポーザブルを呼び出す
            categories.forEach { category ->
                Category(category, tasks) // カテゴリとタスクを渡してUIを生成
            }
        }
    }
}
```

これで実行してみてください。
自分の環境だとiOSもdesktopもAndroidも動きましたが、もし何かエラーが起きたらコメントで教えていただけるとありがたいです。

# まとめ
これでsupabaseとの接続が出来ました。
[次の記事](https://qiita.com/shunk0616/private/283b60fdf8dbbc8aebc9)では、読み取りだけではなく、書き込みと更新の処理を実装して行きましょう。