カバー

Twin:te

8000 人が利用する筑波大生専用の時間割アプリです。私はフロントエンドの開発を中心に参加しています。

どのようなサービスか

Twin:te(ついんて)は有志により運営されている筑波大生のための時間割アプリです。
筑波大学の履修システムに特化しており約 8000 人以上が利用しています。
WEB 版, iOS/Android 版があります。iOS/Android 版は WebView を用いて開発されており実質 WEB 版です。

URL

開発目的

Twin:te は 2019 年から開発されており、私は 2020 年 11 月ごろからこの開発に参加しました。
私が Twin:te の開発に参加した当初の理由は以下のようなものでした。

  • 公式の筑波大学のシステムが不便だから Twin:te の開発に参加してこれを発展し広める手伝いをしたい
  • 技術そのものと同じぐらい「技術をどのように活用して問題を解決できるか」ということにも興味があり、自分が一番のユーザになりうるサービスはそのような問題を試行錯誤するのに良い

技術スタック等

私はフロントエンドを中心に開発しているのでフロントエンドの技術スタックについて大雑把に記載しています。

技術

  • TypeScript
  • Vue.js
  • Storybook
  • Aspida
  • Vite

また以下のようなツールを用いてエラー監視やユーザ行動の定量化に努めています。

  • Sentry
  • Google Analytics
  • Google Tag Manager
  • HotJar

私の関わり方

Twin:te のフロントエンド開発要員は主にエンジニア 2 人で構成されており、私はそのうちの 1 人です。 最近は新しいメンバーも増えており、今後はより複数人で分散して開発できる体制を整えていきたいと考えています。

時間割追加部分の実装

授業を検索し追加する画面を実装しました。PC 版とモバイル版でレイアウトがところどころ異なりデザインデータ通りの実装を行うのに苦労しました。またこの画面はロジックが多く、多様な検索オプション、選択結果の一時保持、既存の時間割との重複チェックなど多様な状態を考慮する必要がありました。

検索画面
検索画面

ユーザ行動の測定の仕組みを導入

現状の Twin:te に足りない部分だと個人的に感じ導入しました。 いままで Twin:te は開発グループの想像や簡単なアンケート、SNS 上の反応を元に開発機能の方向性を決めており数値で開発の方向性を議論できる体制がありませんでした。 そこでユーザ行動を数値的に測定する仕組みを導入しました。目的は 2 つです。

  • 定量的に現状を判断できるようにする
  • 改善前後の変化を定量的に判断できるようにする

Google Tag Manager と Google Analytics のカスタムイベントを Big Query などに流し込んで分析しています。 具体的にはアプリ内の各種ボタンのクリック、授業の検索ワード、スクロール率などなど通常の Google Analytics では計測できない範囲まで詳細にログを取っています。

現状データの収集中であり、今後このデータをもとに分析結果をチーム内に共有し、改善に活かしたいと考えています。

フィードバック機能の実装

フィードバック機能の提案、実装を行いました。

フィードバック画面
フィードバック画面

実装期間がとても短かったこともあり、正直技術的には酷い実装です。しかし大型アップデート直後はユーザの定性的の意見を素早く拾いたかったため実装を急ぎました。そのかいがあってか 150 件以上のフィードバックをいただき改善に役立てることができました。

エラー処理の設計

エラー処理の設計を行いました。とはいえ大したことはしていなく、エラー処理の扱い方について以下のようなことを考え実装しただけです。 最終的には Error Class を Extends したカスタムエラークラスを throw する形式に落ち着きました。
ただ折角エラー周りを整備したものの、現状うまく活用できていないので今後の課題としたいです。 Error Class の実装

  • エラーはどのように上層部に伝播するべきか
    • エラーコードなどを発行するべきか
    • Error Class を Extend するのが良いか
      • Stack Trace なども取りたいし良さそう
  • エラーはどのように受け取るべきか
    • catch(err)errには型が付いていなくて辛い
    • Result型みたいなものを導入するのはどうだろう
  • エラーが発生する処理のたびに try {} catchを書くのは少し辛い
    • Rust の unwrap()みたいなのがほしい

トースト通知の実装

上記のエラー処理に加えて、エラーなどの通知の見せ方も改良しました。 当初の通知は画面全体を覆うポップアップ表示を利用していました。しかしそれには以下のような問題点がありました。

  • 成功や注意など比較的重要度の低い通知も画面を覆ってしまうためユーザの操作を停止してしまう
  • 連続した通知を見られない(「A に成功しました」 → 「B に成功しました」 など)
  • ポップアップで画面が覆われてしまい、エラー内容と現在の操作を見比べられない
    • エラーの内容を一度覚えてから、現状の操作を把握する必要がありユーザの負担が大きい

これらの解決策として私はトースト通知を提案、実装しました。 画像のようにトースト通知とすることで現在の操作を妨げることなく、自分の操作とエラー内容を見比べながらユーザはエラーを回避する行動を取ることができます。

地味な機能ですが、個人的に気に入っているので紹介しました。

トースト通知画面
トースト通知画面