【Jetpack Compose】ViewModel を捨てて Repository を Composable に直結する

 

気になるのはライフサイクル。

 

きっかけ

フル Compose でよくあるTodoのようなメモのようなアプリを作ってみました。

一通りの機能は実装しました。




👉 Jetpack Compose without ViewModel #shorts - YouTube hatena-bookmark

いろいろ Compose を試しながら進んでいくと ViewModel がスカスカになりました。


@HiltViewModel
class TodoViewModel @Inject constructor(
  private val repository: TodoRepositoryInterface
) : ViewModel() {

  val items: Flow<List<Todo>> = repository.load()

  fun insert(text: String) = repository.insert(text)

  fun update(id: Long, text: String) = repository.update(id, text)

  fun delete(id: Long) = repository.delete(id)

}

ViewModel いらなくね?

ViewModel を省略して、Repository を直結します。

 

結果

以下、少しの書き換えで問題なく動きます。


@Composable
fun TodoScreen(
  //viewModel: TodoViewModel = hiltViewModel()
  repository: TodoRepository = TodoRepository(
    Database(
      AndroidSqliteDriver(
        schema = Database.Schema,
        context = LocalContext.current,
        name = "database.db"
      )
    )
  )
) {


//val items by viewModel.items.collectAsState(initial = emptyList())
val items by repository.load().collectAsState(initial = emptyList())


//viewModel.insert(target.text)
repository.insert(target.text)


//viewModel.update(target.id, target.text) 
repository.update(target.id, target.text)


//viewModel.delete(target.id)
repository.delete(target.id)


//viewModel.delete(target.id)
repository.delete(target.id)

画面回転問題なし、メモリーリークもありません。

すんなりです。

Square製 SQLDelight + Flow(coroutine extension) を使っていますが、

Room + LiveData でもいけると思います。

Composable で Flow(LiveData) を受け取った瞬間に、

collectAsState(ObserveAsState) で State に変換できるんなら、

それのほうが良くね?

ライフサイクルの差も気にしなくていいし。

しかし、緩衝国がなくなるのはなんだか不安です。

Hilt で @Singleton で、ぶち込んでやりたかったです。

あ、でもこれ、 re-compose のたびに、Repository インスタンスが...

(つづく...)

👉 「SwiftUIでMVVMを採用するのは止めよう」と思い至った理由 - Qiita hatena-bookmark
👉 ViewModel はいつ生まれていつ死ぬか 【→ Jetpack Compose】 hatena-bookmark
👉 Jetpack ComposeとViewModelについて考える - Blog - Mori Atsushi hatena-bookmark


【Python】「pip search」の代わりは何なの?

モジュールがないといわれるので、


pip search ***

で調べようとしますが、

使えません。

ERROR: XMLRPC request failed [code: -32500] RuntimeError: PyPI's XMLRPC API is currently disabled due to unmanageable load and will be deprecated in the near future.

👉 Remove the pip search command · Issue #5216 · pypa/pip hatena-bookmark

👉 Search results · PyPI hatena-bookmark

代替はこれですかね、「pip-search」 。

ERROR: XMLRPC request failed [code: -32500] RuntimeError: PyPI's XMLRPC API is currently disabled due to unmanageable load and will be deprecated in the near future.

「pip」 にラッパー気味に関数をセットしながら使うといいようです。


alias pip='function _pip(){
    if [ $1 = "search" ]; then
        pip_search "$2";
    else pip "$@";
    fi;
};_pip'

👉 pip-search · PyPI hatena-bookmark

しかしこれ公式ではないですよね?

👉 victorgarric/pip_search: Searching thought pip when hard times strike hatena-bookmark

みんなはどうしてるの?

ブラウザで検索してるの?

最近、python コマンドラインのまわりはいろいろ混乱します。

👉 macOS 12.3 で Python2 が消え、スクリプトが「bad interpreter: /usr/bin/python: no such file or directory」とは。 hatena-bookmark


【iPhone】あなたのスマホが最新絵文字 Emoji 14.0 を表示できるか確認してみよう【Android】

微妙な時期なので確認してみますか。

そのスマホが最新絵文字 Emoji 14.0 を表示できる確認する

まあ、表示できない場合の原因は、フォントであり、その原因は、そのアプリであり、その原因は、OSのそのバージョンであり、などさまざまです。

New Emojis for 2021, 2022 hatena-bookmark

以下、Emoji バージョンごとに3つずつ。

Android 絵文字ポリシー - Play Console ヘルプ
Android 絵文字ポリシー - Play Console ヘルプ hatena-bookmark

表示できていますか。


 ‍ 14.0
‍️ ‍♀️ ‍❤️‍13.1
  ‍❄️13.0
‍ ‍ ‍‍12.1
  ‍‍12.0

表示できていませんね!

同じ端末の同じブラウザで見ていても表示しているサイト側のテキスト処理や指定しているフォントで変わってきます。

以下、Unicode Emoji 14.0 の新規絵文字を貼っておきます。

GitHub Gist の埋め込みでは、右下の「view raw」から出力すると、とりあえずサイトのフォント指定の影響は受けません。

コピーしていろんなとこに貼り付けてみましょう!

顔文字/絵文字辞書 単語リスト - Google Play のアプリ hatena-bookmark