はじめに
前回はsupabaseとの接続の準備のために、アーキテクチャを整えたり、DIを導入したり、インターフェースを作成したりしました。
今回は実際にsupabaseとアプリを接続して、データを表示するところまでやっていきましょう。
supabaseのデータベースからデータを取得する処理を実装
まずは前回作った、TaskApi.ktを編集して、supabaseのデータベースからデータを取得する処理を実装します。
インターフェースを作成する
TaskApi.ktのsealed interface MessageApiを以下のように修正します。
sealed interface TaskApi {
suspend fun fetchAll(): List<Task>
}
実装する
次にTaskApiImplを以下のように修正します。
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を以下のように修正します。
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を以下のように修正します。
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との接続が出来ました。
次の記事では、読み取りだけではなく、書き込みと更新の処理を実装して行きましょう。