通知エリアからツイートするAndroidアプリ、Monotweetyを公開した(コードもあるよ)

header

掲題のとおり、アプリを Google Play Storeに公開しました。(2022/08更新: 公開終了しました)
今回はコードもGitHubで公開してます。Apache v2です。

名前は"Monotweety"。「モノツイーティ」と読みます。

機能はホントにシンプルで、「通知エリアからツイートする」だけです。

実際のところ通知エリアからツイートできるのはAndroid 7.0以降の端末だけで、それ未満の端末では通知をタップすると編集ダイアログが表示されます。

  1. 通知から

notification

  1. 直でツイート

direct tweet

  1. Android 7.0未満ではダイアログから

from dialog

モチベーション

  • ひとりごとみたいにツイートすることが多いのでツイート特化型アプリがほしい
  • 既存の通知エリアからツイートできるアプリは古くてメンテされてるか不明なものばかり
  • 今風のかっこいいデザインのアプリがほしい
  • Android NでDirect Reply(通知から直で返信できる機能)が追加
    -> あれ、これ使えるんじゃ…?

という感じ。

要件は下記の通り

  • 通知エリアからツイートできること
  • 文字数超過したら編集できること

で、この他にお遊びみたいなものだけどいわゆる「連ツイ(in reply toでツイートをつなげる)」機能もつけてみました。

Direct Replyで用意されているのはカスタマイズができない入力エリアなので、文字数チェックは送信ボタンを押した後に行っていて、超過していた場合は編集用の画面が立ち上がる作りになっています。

今回はだいたいコーディングだけで102時間くらいかかったらしい(wakatime調べ)。

アプリ名の由来?

"Monochrome"ではなく"Monologue"のmonoです。
最初は"Monologue"で作ろうとしたけど案の定すでにTwitterに登録済みのアプリがありました…
Omnitweetyというアプリもリリースしてますが、特に「Omni - Mono」で対になる、とか特に狙ったわけではないです。

※ここから下は技術者向け ----------

使ったライブラリとか

網羅的なものはbuild.gradle見てもらうとして、主要なものを軽く紹介します。

Kotlin

最近流行りのアレ。
拡張関数とかdata classとか、とても便利です。
あとリスト操作関数が充実しててめちゃくちゃ捗ります。

Conductor

Viewベースのアプリケーションを作るためのフレームワーク。
数年前にSquareがFragment使わないぞ!って記事をだしていましたが、その流れのライブラリですね。

Fragment使いたくないけどどうすんの?って言われた時に候補としてまず挙がるのはSquare製のMortar/Flowだと思いますが、こちらのConductorはMortar/Flowよりもかなりシンプルな作りになっています。

Mortar/FlowはDaggerと一緒に使う前提で作られてるような感じで、SystemServiceにカスタムのServiceを追加したりいろいろ前準備が多くて「なるほどわからん」状態だったけれども、こちらは完全に"better fragment"にフォーカスしているような印象です。

DaggerだとかMVPだとかMVVMとかそういうのは開発者側で勝手にやってくれという方針なのでライブラリとして迷いどころは少なく、とても扱いやすかったです。なにより、サンプルが豊富で非常に助かりました。

ちなみにLollipop以上だったらちゃんと画面間のShared Element Transitionも行えます。

Dagger2

とてもイケてるDIライブラリ。そういえば本家SquareのDagger1はdeprecatedになってましたね。
今回のComponent構成はこんな感じ。

AppComponent ─ UserComponent ┬ SettingComponent
  │                          └ ComposeStatusComponent

  └ ActivityComponent ┬ SplashComponent
                      └ LoginComponent

グローバルなAppComponentの下にユーザ毎に作られるUserComponentがあります。
ユーザ情報が必要な各画面のComponentはUserComponentを親に持ちます。
ユーザ情報が必要ない画面のComponentはActivityComponentを親に持ちます。

ここ、図の上ではSettingComponent/ComposeStatusComponentはActivityComponentに依存してないように見えますが、実はActivityComponentで管理されているインスタンスを、Componentに渡すModule経由で引き回してたりします。

これはActivityがUserComponentの作成より前(ログイン確認より前)に作られるのが原因です。
Daggerでは複数のScoped Componentを親に持つことができないので、苦肉の策としてこのようにActivityComponentで管理されているインスタンスを渡す形にしました。
うまいやり方があればいいのですが。

StorIO

SQLiteをリアクティブに扱うライブラリ。
よりいろいろやってくれるSQLbrite、って感じでしょうか。
Not ORM。

モデルとクエリの結果をマッピングするリゾルバクラスを生成するアノテーションプロセッサも用意されてますが、Kotlinはサポートされてないので手動で書く必要があります。

今回実はSQLite使う必要特になかったのですが、アーキテクチャのデモ的な側面もあったのでSQLite入れてます。
GitHub上にAndroidアプリに様々なアーキテクチャ適用してみたよ系のデモレポジトリって結構あるのですが、だいたいAPI通信とメモリキャッシュまでで止まっててじゃあその先どう考えてるの? って思うことが多かったので使ってみた次第。

ともあれ、StorIOはAPIもきれいでわかりやすいので、リアクティブに使えるSQLiteライブラリを探している方は試してみてはいかがでしょう。

アーキテクチャ

前作のOmnitweetyでは、Android Clean Architectureを採用しました。ほとんど写経です。
MonotweetyではAndroid Clean Architectureを踏襲しつつも諸々シンプルに再構成しています。
たとえばDataSource周りのファクトリクラスを廃止してみたり、機能ごとのパッケージ構成にしてみたり。
DataSourceの差し替えとか実際にアプリの実行中に発生することなんてほぼないので、まあ必要ないよねー、という判断です。

あ、あとView周りに関してはMVPではなく、MVVMっぽいアーキテクチャとなっています。
開発が佳境だった頃にKotlinのAndroid Studio PluginとDataBindingの相性が非常に悪かったので今回は地道にbinding処理書いてますが、Kotlin 1.0.5でだいぶ改善したらしいのでそのうち書きなおすのもやってみたい。

アイコン

アイコンはOmnitweetyと同様、99designsを使っています。
今回はコンペではなく、Omnitweetyのコンペの時に最後まで悩んで落としてしまったデザイナーさんにお願いしました。
前回同様とてもかわいらしいアイコンが仕上がって満足しています。

こちらからは以上です。

参考: