why
ステートに持った値を保存したい。
DB にはまだ繋がず、とりあえず Datastore に保存する。
Gauge のアプリでレスポンスを シナリオデータストアに入れていたように
Android でもデータストアに入れる。
https://www.youtube.com/watch?v=aQyphCXeVHg&list=PLgAI_5b_7BdRaBPAD5RMrzjoSwefDXpkw&index=7
SharedPreference という名前で使えるらしい。
Datastore Preferences 1.0 をインポート
dependencies {
//...
implementation 'androidx.datastore:datastore-preferences:1.0.0'
}
App の build.gradle の dependecies の implementation で
androidx の datastore の datastore-preferences:1.0.0
これを書き、 sync してインストールする
Repository (Driver) を作成して Datastore に書き込めるようにする
https://www.youtube.com/watch?v=uvAbY38CNXU&list=PLgAI_5b_7BdRaBPAD5RMrzjoSwefDXpkw&index=8
コンポーザブルからは呼び出すだけで、処理担当を分ける。
実際にデータを書き込む処理は、Repository に書く。
クリーンアーキテクチャで言う、Driver 相応だろう。
現状、アプリのディレクトリ構造として
- screen / edit / EditNoteScreen.kt
- ui / theme /
- MainActivity.kt
- NoteApp.kt
この構造になっている。
ここに package として repository / を追加する。
その中にインターフェースとして NoteRepository を作る。
Drive というより、インターフェースだから Port っぽいな
インターフェースである reposotiry / NoteRepository で save と load を定義する
実装する前のインターフェースとして、クリーアーキテクチャで言う
Port のようなものを作る。実装と呼び出し先を繋げるものだ。
ここでは save と load を作る。
package com.example.hellojetpack.repository
interface NoteRepository {
suspend fun save(body: String)
suspend fun load(): String
}
インターフェースを TODO で実装する repository / datastore / DatastoreNoteRepository で save と load を実装する。
とりあえず TODO で実装する。
実際の実装クラスを書く。
クリーンアーキテクチャでいう Driver のパッケージに書くものだ。
MokeLab さんのやり方では Repository パッケージの中に
さらに datastore パッケージを作って、中に書くらしい。
なので、先ほど作った repository / のなかに datastore / を作って、その中に DatastoreNoteRepositrory.kt を作った。
class DatastoreNoteRepository: NoteRepository {
override suspend fun save(body: String) {
TODO("Not yet implemented")
}
override suspend fun load(): String {
TODO("Not yet implemented")
}
}
中身は、NoteRepository のインターフェースを
implement members してガワを作った。
DatastoreNoteRepository のために Context に noteStore というプロパティを用意する。
https://www.youtube.com/watch?v=uvAbY38CNXU&list=PLgAI_5b_7BdRaBPAD5RMrzjoSwefDXpkw&index=8
この Android X のデータストアを使うためには Android の Context を使って、その中にプロパティを用意する必要があるらしい。
Context とは、React における Redex のような、どのコンポーザブルからでも読み書きのできる置き場所だと解釈する。
https://developer.android.com/topic/libraries/architecture/datastore?hl=ja#preferences-create
Kotlin ファイルの最上位、つまり一番最初にインスタンスが一度作られるらしい。そしてシングルトンで保持できるらしい。
https://e-words.jp/w/%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%AB%E3%83%88%E3%83%B3.html
シングルトンとは、一つしかインスタンスが作られないことで、つまり共通データにアクセスされるコンテキストのことだと解釈する。
import android.content.Context
import androidx.datastore.preferences.core.Preferences
val Context.noteStore: DataStore<Preferences> by preferencesDataStore(
"note"
)
Android Context のなかに noteStore と言うプロパティを作成
型は先ほど依存に追加した Android X DataStore の Preferences とする。
これで Gauge で言う Scenario Datastore のように
Android の Preference Datastore として
キーバリューストアが使えるようになると解釈した。
PreferencesDatastore のための Preference Key を用意する
https://youtu.be/uvAbY38CNXU?t=200
val BODY_KEY = stringPreferenceKey("body")
データストアは キーバリュー ストアなので
次はキーを作る。
Preference Datastore を作ったので、対応する
Preferecne Key を作った。
Context.noteStore に Repository の save メソッドで引数のキーと中身の値が入るようにする。
val Context.noteStore: DataStore<Preferences> by preferencesDataStore(
"note"
)
class DatastoreNoteRepository: NoteRepository {
override suspend fun save(body: String) {
TODO("Not yet implemented")
}
override suspend fun load(): String {
TODO("Not yet implemented")
}
}
現状、Preference の Datastore を使って
Context に noteStore プロパティを生やしている。
save メソッドの中身には何もない。
class DatastoreNoteRepository(
private val context: Context
): NoteRepository {
override suspend fun save(body: String) {
TODO("Not yet implemented")
}
}
コンストラクタ インジェクションで
クラス生成時に一度だけ context インスタンスができるようにする。
override suspend fun save(body: String) {
context.noteStore.edit { pref ->
pref[BODY_KEY] = body
}
}
引数の body を
ストアの BODY_KEY と言うキーのバリューとして入れる。
Top comments (0)