nzw.jp
/
開発ノート
/
MyDictly
M
PRODUCT NOTE / PRD
MyDictly
2 言語を、つなぐ単語学習アプリ。旧名 LangBridge この文書は「何ができるか」ではなく、なぜ・誰のために・どんな判断で作ってきたか を記録した開発ノートです。
TL;DR
ひとことで
MyDictly は、自分で作った単語リスト(スプレッドシート)を取り込み・フラッシュカードで暗記・Google Sheets へ書き戻し までまとめて行える、シンプルな 2 言語対応の単語学習アプリです。巨大な辞書 DB は自前で持たず、外部辞書へのリンクと外部 API に委ねる ことで、アプリは「自作単語帳の管理と学習」に集中します。ソースコードは GitHub で公開しています。
Problem
背景・解きたい課題
自分で単語を集めて覚えたい学習者には、次の壁があった。
自作の単語リストが活かせない — スプレッドシートで管理した語彙を、暗記・検索・同期できるアプリが少ない。
辞書を何度も行き来する手間 — 単語を調べるたびに複数の外部辞書サイトを開き直すのが面倒。
英語以外のペアで学びにくい — 多くのアプリが英語特化で、任意の 2 言語ペアの語彙学習に向かない。
複数端末で持ち歩けない — 単語帳が端末に閉じていると、環境を変えると続かない。
MyDictly はこれを「スプレッドシートを軸に、取込・暗記・同期・辞書リンクを 1 つにまとめる」 ことで解く。
Who
ターゲットユーザー
プライマリ
自分でスプレッドシートに単語を集めて覚えたい語学学習者。当初は中国語⇄日本語を起点にし、現在は言語に依存しない設計(18 言語の読み上げ対応)へ広げている。
主なユースケース
スプレッドシートの単語を一括取込
フラッシュカードで音声付き暗記
外部辞書リンクからすぐ深掘り
Solution & Scope
解決策とスコープ
コア機能(In scope)
Google Sheets 一括取込(列マッピング自動・重複制御)
インクリメンタル検索(曖昧/前方/完全一致)
フラッシュカード学習(表裏に音声読み上げ・18 言語)
外部辞書リンク統合(Google/Weblio/北辞郎ほか)
Google Sheets へのエクスポート
AI アシスト・AI 深掘り(意味・例文)
Firebase によるデバイス間・自動同期
やらないこと(Non-goals)
自前の巨大辞書 DB は持たない(外部辞書に委ねる)
会話・ロールプレイ学習(Engly が担当)
習慣トラッキング(DayGrid が担当)
Success Metrics
成功指標(KPI)
「自作単語帳が回り、続く」状態になっているかを、次の指標で見る。数値は目標仮置き
3+ 回/週
フラッシュカード利用 (暗記が回るか)
Decision Log
主要な意思決定ログ
各アップデートの裏にある「なぜ」を、決定・仮説・結果の 3 点で残す。理由は変更内容から再構成
v1.4.0 「辞書を持たない」方針を一部撤回し、辞書は持つが単語帳とは別枠にする
DECISION
PDIC 形式の辞書ファイルを取り込めるようにした。ただし取り込んだ語は単語帳(DictionaryEntry)に流し込まず、引くためだけの参照辞書 として別に保持する。検索結果には「辞書」欄として出るが、マイ単語一覧には現れず、習熟度もお気に入りも持たない。単語カードに混ぜて出題することはできるが、その結果は保存しない。
WHY / 仮説
「自前辞書を持たない」という初期の判断は、外部辞書 API が使える前提で成り立っていた。実際には API の URL が未設定だと辞書欄が丸ごと無反応になり、オフラインでは何も引けない。一方で単純に辞書を取り込んで単語帳に入れる案は破綻する——単語帳の保存は単一 JSON なので、数万〜数百万語を流し込めば読み書きのたびに全体を舐めることになる。そこで「辞書は資産として持つが、単語帳のデータモデルには入れない」と線を引いた。PDIC を選んだのは、形式自体がソート済みインデックス+固定長ブロックというランダムアクセス向けの構造で、全件をメモリに載せずに引ける ため。加えて日本語圏の個人作成辞書がこの形式で多く流通している。
RESULT
10 万語規模の辞書でも、二分探索で触れた見出語だけを復号するので 17 回程度の比較で引ける。単語帳側のデータ量は辞書を入れても増えない。代償として、辞書の語には習熟度が付かない——覚えたい語は単語帳へ手で登録し直す必要があり、ここは今後の課題として残した。
v1.4.0 BOCU-1 デコーダを自前で移植する
DECISION
PDIC/Unicode 辞書の文字符号化である BOCU-1(Unicode UTS #6)のデコーダを、リファレンス実装(C)から Dart へ移植した。デコードのみ実装し、エンコーダは往復テスト用にテストコード側へ置いた。
WHY / 仮説
pub.dev に Dart 実装が存在しなかった。辞書対応を諦めるか、仕様を読んで書くかの二択で、後者を選んだ。判断材料は分量よりも「検証できるか」で、UTS #6 にはテストベクタがあり、エンコーダを書けば往復テストで正しさを機械的に確かめられる。仕様が固定されていて後から変わらない領域なので、一度書けば保守コストはほぼ発生しないとも見た。
RESULT
辞書を原本のまま読めるようになった——取り込み時に独自形式へ変換しないため、変換の待ち時間もディスクの二重消費も発生しない。BOCU-1 の「0x00〜0x20 の大半を出力しない」「バイト列の大小がコードポイントの大小と一致する」という性質が、そのまま終端判定と二分探索に使えている。
v1.4.0 取り込み口を増やすのではなく、行列に落としてから 1 か所に集める
DECISION
Excel(.xlsx)と CSV / TSV の取り込みを追加するにあたり、取り込み元ごとの処理を作らず、すべてを List<List<String>> の行列へ落としてから共通の ImportRowsUseCase に通す形にした。ファイルの種類は拡張子ではなく中身のバイト列 で判別する。
WHY / 仮説
列マッピング・重複判定・取り込みセッションの記録は、元がスプレッドシートでも Excel でも同じ扱いでよい。取り込み元ごとに分岐を増やすと、この 3 つが経路の数だけ複製される。拡張子を捨てたのは実地の事情で、配布サイトによっては .dic が download_file.php のような名前で落ちてくるうえ、iOS の「ファイル」App 経由でも拡張子が当てにならない。
RESULT
取り込み元が 2 つ増えても、列マッピング画面と重複判定は 1 実装のまま。判別をバイト列に寄せた副産物として、名前が壊れたファイルでも正しく振り分けられ、旧形式の .xls だけは「読めない」と明示的に案内できるようになった。
v1.4.0 アプリ名を MyDictly に改め、識別子は据え置く
DECISION
表示名を LangBridge から MyDictly へ変更し、アイコンも刷新した。変えたのは表示名だけ(ホーム画面・ストア表示・Web manifest・Google Sheets への書き出し名)で、バンドル ID jp.langbridge・配布 URL・GitHub リポジトリ名は据え置いている。v1.4.0 で反映した。
WHY / 仮説
LangBridge という名前を持つアプリ・サービスが他に複数あり、ストアでも検索でも自分のアプリを指し示せなくなっていたのが発端。候補は「自分の辞書」という意味を軸に選んだが、辞書=Jisho を織り込んだ案は日本語を知らない人に一切伝わらないため落とした。最終的に dictionary の一般的な短縮である "dict" と、Bitly / Calendly と同じ -ly を組み合わせ、日本語話者以外でも意味が取れる形にした。一方で識別子まで変えると APK 直配布のアップデート経路と Firebase 連携が切れ、既存ユーザーが更新を受け取れなくなる。だから「見える名前」と「動かす名前」を分け、変更は前者に限定した。
RESULT
名前の重複は解消し、既存ユーザーはアップデート経路を保ったまま改名版を受け取れる。配布ファイル名は MyDictly.apk へ切り替えたが、バンドル ID とリポジトリ名(lang-bridge)は旧名のまま残り、対外的な名前が二重に存在する状態は当面許容している。
design 自前辞書を持たず、外部辞書リンク+外部 API に委ねる
DECISION
巨大な辞書データベースを自分で抱えず、Google/Weblio/北辞郎などの外部辞書へのリンクと外部 API に検索を委ねた。
WHY / 仮説
辞書 DB の構築・保守は個人開発では負担が大きい。既存の辞書資産にリンクで乗り、アプリは「自作単語帳の管理と学習」という独自価値に集中すべきだと考えた。
RESULT
軽量なまま、任意の言語ペアで実用的な検索・学習を提供。アプリの主戦場を明確にした。
※ この判断は v1.4.0 で一部撤回した。 外部 API の URL が未設定だと辞書欄が丸ごと無反応になり、オフラインでは何も引けないという穴が実際に効いたため。ただし撤回したのは「辞書を持たない」の部分だけで、辞書は単語帳とは別枠の参照専用として持つことにした(上の v1.4.0 のエントリを参照)。
AI AI 機能に利用制限を設け、月間利用数を可視化する
DECISION
AI アシスト・AI 深掘りに利用上限を設け、月間利用数をヘッダーに表示。バックエンドの生成 AI 利用も制限を強化した。
WHY / 仮説
生成 AI は 1 リクエストのコストが高く、無制限だと濫用や費用で持続不能になる。上限と可視化で、無料提供と持続可能性を両立させる必要があった。
RESULT
ユーザーが残り利用数を把握でき、運用コストを抑えながら AI 機能を提供し続けられる形に。
v1.3.6 アプリ内アップデート機構を共通基盤へ刷新する
DECISION
APK 直配布のアップデート機構を共通基盤(nzw_app_updater)へ移行し、更新に失敗した場合はサーバーから案内・手動ダウンロードリンクを出せるようにした。
WHY / 仮説
複数アプリで更新機構を個別実装すると保守が破綻する。共通化し、かつ更新失敗時もサーバー側から救済できる導線を持つべきだと考えた。
RESULT
更新の安定性が向上し、meta を編集・デプロイするだけで全ユーザーの更新ダイアログに案内を出せる運用に。
Milestones
これまでの歩み
v1.4.0 2026-08-20 MyDictly へ改名/PDIC 辞書の取り込み(参照専用)/Excel・CSV 取り込み/iOS を App Store へ提出
v1.3.7 2026-07-12 リリース署名鍵へ切替(Play プロテクト警告を軽減/要再インストール)
v1.3.6 2026-07-04 アップデート機構を共通基盤へ刷新/更新失敗時のサーバー案内
v1.3.4 2026-06-08 フラッシュカードの音声読み上げ(18 言語)/Web 版の自動同期
v1.3.3 2026-05-22 Firebase 連携でデバイス間同期/スプレッドシート自動同期
v1.1.0 2026-04-29 AI 辞書アシスト・検索履歴を追加
v1.0.0 2026-04-26 初回リリース(辞書検索・Google Sheets 同期・フラッシュカード・単語管理)
全バージョンの変更履歴を見る →
Roadmap / Open Questions
これから
対応言語ペア・読み上げ言語のさらなる拡充。
AI による例文・解説の質の向上と、学習フローへの自然な組み込み。
オープンソースとしての貢献者の受け入れ(Fork・PR 歓迎)。
未決事項:AI 利用制限の最適値、独自クラウド同期と Google Sheets 同期の役割分担。
© 2026 nzw. All rights reserved.