GitHub Search
GitHub API を利用して GitHub のリポジトリを検索するアプリです。株式会社ゆめみのFlutterエンジニアコードチェックの要件を満たすよう実装しています。
本アプリを通して自分なりの最適なアーキテクチャを確立し、リファレンスコードにすることを目的にしています。
⚠️ 注意 このアプリは
GitHub APIを利用するために GitHub のアクセストークンをアプリの内部でハードコーディングして保持する構成になっています。このアプリを公開すると悪意のある者にアクセストークンを抜き取られ悪用される恐れがありますのでお控え下さい。もちろん、手元でビルドして動かすことは問題ありません。
アプリの機能
- シンプルな UI / UX
- GitHub リポジトリの検索と詳細表示
- 無限スクロール対応
- go_router を使った新しいルーティング
- http を使った REST API の実装
- 多言語対応(日本語/英語)
- カスタムフォント対応
- mockito を使った Unit / Widget テスト
- flutter_launcher_icons を使ったアプリアイコン
- flutter_native_splash を使ったスプラッシュ画面
- GitHub Actions による自動テストと自動ビルド
- サポートするプラットフォーム
- iOS / Android / Web / macOS / Windows
今後対応予定
- hive or shared_preferences の利用
- Integration テスト
- テーマ対応
- ダークモード対応
- よりよい UI / UX
対応しないこと
- Firebase 連携
- Flavor 対応(develop / staging / production などの環境分け)
アーキテクチャ / パッケージ
- flutter_riverpod + state_notifier + freezed + go_router
- CODE WITH ANDREA の下記アーキテクチャを参考にしています。本アプリでは、Application Layer は省略しています。
- 本アプリの依存関係図です。
%%{init:{'theme':'base','themeVariables':{'primaryColor':'#f0f0f0','primaryTextColor':'#2f2f2f', 'lineColor':'#2f2f2f','textColor':'#2f2f2f','fontSize':'16px','nodeBorder':'0px'}}}%%
graph TD
subgraph プレゼンテーション層
IndexPage(一覧ページ<br>StatelessWidget) --> SearchTextField(検索テキストフィールド<br>ConsumerWidget)
IndexPage --> ListView(一覧 View<br>ConsumerWidget)
SearchTextField --> SearchText([検索文字列<br>String])
ListView --> ListViewState([一覧 View 状態<br>State])
ListViewState --> ListViewController(一覧 View コントローラ<br>StateNotifier)
ListViewController --> SearchText
ViewPage(詳細ページ<br>StatelessWidget) --> DetailView(詳細 View<br>ConsumerWidget)
DetailView --> DetailViewState([詳細 View 状態<br>State])
DetailViewState --> DetailViewController(詳細 View コントローラ<br>StateNotifier)
DetailViewController --> ViewParameter([オーナー名とリポジトリ名<br>Equatable])
end
subgraph データ層
ListViewController --> RepoRepository(リポジトリ用リポジトリ)
DetailViewController ---> RepoRepository
RepoRepository --> GitHubRepoRepository(GitHub 向けリポジトリ用リポジトリ)
subgraph DTO
GitHubRepoRepository --> GitHubHttpClient(GitHub 向け HTTP クライアント)
GitHubRepoRepository --> GitHubApiDef(GitHub API 定義)
end
subgraph データソース
GitHubHttpClient --> GitHubApi(GitHub API)
end
end
subgraph 環境変数
SearchText --> EnvSearchText{{検索文字列初期値<br>String}}
GitHubHttpClient ---> EnvAccessToken{{アクセストークン<br>String}}
end
classDef widget fill:#4063DD, color:#ffffff;
classDef controller fill:#4063DD, color:#ffffff;
classDef state fill:#BDB5F4, color:#ffffff;
classDef repository fill:#437C40, color:#ffffff;
classDef env fill:#7c7d7c, color:#ffffff;
class IndexPage,ViewPage,ListView,SearchTextField,DetailView widget;
class ListViewController,DetailViewController controller;
class SearchText,ListViewState,DetailViewState,ViewParameter state;
class RepoRepository,GitHubRepoRepository,GitHubHttpClient,GitHubApiDef,GitHubApi repository;
class EnvSearchText,EnvAccessToken env;
一覧 Viewが更新される例一覧 Viewの依存関係は、一覧 View→一覧 View 状態→一覧 View コントローラ→検索文字列となっています。ユーザが検索文字列を変更し検索を実行した場合、検索文字列が更新されます。すると検索文字列に依存している一覧 View コントローラが更新され、リポジトリ用リポジトリに検索文字列を与えてリポジトリの検索を実行し、その結果をもとに一覧 View 状態を更新します。すると一覧 View 状態に依存している一覧 Viewがリビルドされて再描画されます。
詳細 Viewへの画面遷移の例一覧 ViewのListTileがタップされるとオーナー名とリポジトリ名を表示したい内容に更新して詳細ページに画面遷移します。詳細画面が開くと詳細 Viewがビルドされ、詳細 View コントローラも作成されます。詳細 View コントローラはオーナー名とリポジトリ名をリポジトリ用リポジトリに与えてリポジトリの取得を実行し、その結果をもとに詳細 View 状態を更新します。すると詳細 View 状態に依存している詳細 Viewがリビルドされて再描画されます。
フォルダ構成
| フォルダ名 | 説明 |
|---|---|
/ assets |
assetsにアクセスする自動生成されるユーティリティクラス |
/ config |
アプリケーション、定義値、環境変数 |
/ entities |
モデル層のファイルリポジトリの戻り値に使うエンティティプレゼンテーション層で使うエンティティ(_data suffix がつく) |
/ localizations |
言語ファイル(arb ファイル)、flutter gen-l10n で生成されるクラス |
/ presentation / pages |
プレゼンテーション層のファイル画面Widget |
/ presentation / widgets |
プレゼンテーション層のファイル部品Widget、Controller、State |
/ repositories |
データ層のファイルリポジトリ、データソースデータソースはサブディレクトリで管理 |
/ utils |
拡張機能、ロガーなど便利クラス |
環境
| Version | |
|---|---|
| Xcode | 13.3 |
| Android Studio | Bumblebee 2021.1.1 Patch 2 |
| Flutter | 2.10.3 |
| Swift | 5.6 |
| Kotlin | 1.6.10 |
| Chrome | 99 |
対象 OSバージョン
| OS Version | |
|---|---|
| iOS | 9.0 ~ 15.4 |
| Android | 8.0 ~ 13 |
ビルド方法
- カレントディレクトリで下記コマンドを実行してください。
bin/flutter_envは引数で与えられた環境変数を基にビルドに必要なlib/config/env.dartを作成してくれます。- 作成された
lib/config/env.dartを直接編集しても大丈夫です。
bin/flutter_env -g [アクセストークン] -s [検索文字列の初期値]
| パラメータ名 | 説明 | |
|---|---|---|
-g [アクセストークン] |
Must |
値には GitHub 個人アクセストークン を設定してください。 |
-s [検索文字列の初期値] |
Optional |
好きな文字列を設定してください。指定しない場合は空文字が設定されます。 |
-h |
ヘルプを表示します。 |
- Configurations を選択してビルドしてください
| Configurations 名 | 説明 |
|---|---|
app |
アプリ(iOS / Android)向け |
web |
Web 向け |
コードの自動生成
arbファイルを変更した場合やfreezedを使ったdartファイルを変更した場合は下記コマンドを実行してください。
bin/flutter_gen
テスト
- ローカルでテストを行うためには事前に次のライブラリをインストールしてください。
# lcov のインストール
brew install lcov
# dart_dot_reporter のインストール
flutter pub global activate dart_dot_reporter
- ローカルでテストを行う場合は下記コマンドを実行してください。
- 静的解析 => テスト => カバレッジの結果を表示 を行います。
bin/flutter_test
API ドキュメント
-
API ドキュメント で公開しています。
-
ローカルで生成する場合は下記コマンドを実行してください。
bin/dartdoc
CI
- GitHub Actions を利用して CI を構築しています。
- プルリクエストが作成や更新された時、もしくは
mainまたはdevelopブランチにpushされたときに CI が発火します。
- プルリクエストが作成や更新された時、もしくは
%%{init:{'theme':'base','themeVariables':{'primaryColor':'#f0f0f0','primaryTextColor':'#2f2f2f', 'lineColor':'#2f2f2f','textColor':'#2f2f2f','fontSize':'16px','nodeBorder':'0px'}}}%%
flowchart LR
Start((開始)) --> Analyze(静的解析)
subgraph テスト
Analyze --> Test(単体テスト)
Test --> UploadCoverage(Codecovに結果を送信)
end
subgraph ビルド
UploadCoverage --> BuildAndroid(Androidビルド)
UploadCoverage --> BuildiOS(iOSビルド)
UploadCoverage --> BuildWeb(Webビルド)
UploadCoverage --> BuildMacOS(macOSビルド)
UploadCoverage --> BuildWindows(Windowsビルド)
UploadCoverage --> CreateApiDoc(APIドキュメント作成)
CreateApiDoc --> DeployGitHubPages(GitHubPagesにデプロイ)
end
subgraph レポート
BuildAndroid ---> NotifySlack(Slackに結果を送信)
BuildiOS ---> NotifySlack
BuildWeb ---> NotifySlack
BuildMacOS ---> NotifySlack
BuildWindows ---> NotifySlack
DeployGitHubPages --> NotifySlack
end
NotifySlack --> End((終了))
classDef anchor fill:#4063DD, color:#ffffff;
classDef testJob fill:#4063DD, color:#ffffff;
classDef buildJob fill:#d32f2f, color:#ffffff;
classDef reportJob fill:#437C40, color:#ffffff;
%% class Start,End anchor;
class Analyze,Test,UploadCoverage testJob;
class BuildAndroid,BuildiOS,BuildWeb,BuildMacOS,BuildWindows,CreateApiDoc,DeployGitHubPages buildJob;
class NotifySlack reportJob;
ライセンス
MIT

