本当にリリースできる？FlutterでQiitaアプリを作った話。 

![poster_new.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678085/27dcb69c-c257-7add-27aa-0a723fe70ada.png)

## はじめに
昨年の春先からFlutterを触り始めて、状態管理シリーズの記事や「Dart vs Swift」の翻訳を出してきたが、いつかFlutterで自作アプリを出したいとの思いが強くなり、今回のQiitaアプリに至りました。

####ダウンロード先
▼iOS
https://apps.apple.com/jp/app/open-qiita/id1590830106

▼Android
https://play.google.com/store/apps/details?id=com.jamestong.open_qiita

## Open Qiitaの技術要素
- 状態管理
グローバル状態、例えば記事本文の文字サイズ変更、テーマカラーの変更は**BLoC** + **Equatable**；
特定イベントの状態あるいは通知、例えばログイン＆ログアウト、「好き」に記事の保存＆削除、ホーム画面のスクロール距離によってナビバーの伸縮、閲覧履歴の保存＆削除は**EventBus**；

- ストレージ
「好き」に保存した記事のデータ、閲覧履歴に保存した記事のデータは**sqflite**,　sql文が使えるのですごく便利；
アカウント情報周りやタグリストといったような軽量データは**shared_preferences**、ネイティブ側のSharedPreferences、NSUserDefaultsと同じ；

- http通信　
**dio**を使用。各種apiが完備で非常にパワフル；

- 画面状態の保持
ナビバーの3タブ(人気、タグ、好き)は記事リストはメインのため、画面の切り替えでまたリビルドされるのは嫌なので生きる状態をそのまま保持している。それに対して、その３画面にUIの変化があったらどうする？これも工夫したところ；

- UI
基本的には**cupertino**、**material**をインポートして各プラットフォームに準じて表示するが、何よりアピールしたいのは**CustomPainter**を使ってキャンバス上に図形を自作した。そして、 **CurvedAnimation**, **AnimationController**などを使ってアニメーションを作った。スプラッシュ画面、ローダー、ポップアップダイアログなどの画面でもそのパフォーマンスが感じれる；
以下のOpen Qiita風車は一例↓
![logo_windwill.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678085/8d9c6801-413d-90bd-910a-ebfdd309b6e5.gif)

- レイアウト
画面やWidgetをオーバーフローしないように定義しているため、端末を回転しても問題なし；

## 苦労したところ
- qiita-embed-ogp

qiita側から記事の本文をそのままhtmlで返されるため、解析（パース）するところはすごく大変でした。もちろんUrl一本でそのままwebviewを使って表示するのも一択ですが、そのようなやり方は私あまり好ましくない。😁

通常のhtmlタグについて3rd-party解析ライブラリーでなんとなく解決できるが、中にも`qiita-embed-ogp`のようなqiita独特なタグが存在し、自力でHtmlDocumentからそのタグを取り出して、またloop処理でそのタグ及びバリューを一々書換し、新しいhtmlの要素にスプライシングしなければならなかったです。

## リリースに向けて
- AppIcon
**figma**で作成。


- スクリーンショット
シミュレーターで画像を撮って**figma**で作成。

- 審査対応
出す前にこれで本当に大丈夫なのか自問したので、事前にコロナ関連の記事、「covid-19」や「コロナ」を検索できないようにアプリ内で制御しました。でもやっぱり、アップルからリジェクトのメールが来ました。

>**Guideline 4.8 - Design - Sign in with Apple**
Your app uses a third-party login service, but does not offer Sign in with Apple. Apps that use a third-party login service for account authentication need to offer Sign in with Apple to users as an equivalent option.
**Next Steps**
Please revise your app to offer Sign in with Apple as an equivalent option for account authentication.

参った！qiitaアカウントの`third-party login`はこっちから提供したものではないじゃん。qiitaさんに聞いてくれよ。。。しかし、指摘に対応しなければならないと思い、qiitaのログインwebページにある`third-party login`を全部ブロックしてあげました。
![thumbnail_reject.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678085/e26fae40-2b76-6327-eafb-1a60df50d7a9.png)

そして、もう一回審査に提出したら、以下のような指摘が来ました。

>- Does your app access any paid content or services?
- Do individual customers pay for the content or services?
- If yes, where do they pay, and what's the payment method?
- How do users obtain an account?

またアカウント周りの質問です。仕方がなく、一つ一つ真面目に回答してその夜にやっと承認されました。

ちなみに、google playの方がそんなめんどくさいことがなく、一回で審査に通りました。

## Open Qiita の特徴
1. 最近の人気記事をQiitaサイトと同時にお届けします。さらに、週間人気タグランキングも掲載しており、ワンタップでそのタグに付いた人気記事リストもチェック可能。

2. タグの表示だけでなく、表示中のタグや追加可能のタグを長押し、ドラッグ＆ドロップでタグページの表示をカスタマイズできます。

3. キーワードを入力することで関連記事を検索できます。「関連順」、「新着順」、「LGTM件数順」のような条件で検索結果の表示順番を変えられます。

4. 気に入った記事を「好き」に保存してオフラインでも楽しめます（記事本文に動画や画像を含む場合、動画や画像を表示しないことがあります）。「好き」に保存した記事のリストを長押しで部分削除や全部削除など編集可能。

5. 記事へのコメント投稿(Qiitaアカウント認証を行う必要があります)、コメントリストの閲覧はもちろん、SNSでその記事をシェアすることもできます。

6. マイページ機能を利用して自分の基本情報をチェックしましょう（Qiita アカウント認証を行う必要があります）。

7. 豊富なテーマカラーに加えて記事本文の文字サイズも選択可能で、快適な閲覧環境を作ります。

8. Qiitaの記事量は膨大で何を読んだのかを確認できるように閲覧履歴機能も開発（同じ記事を複数回読んだ場合は一回目のデータしかトラッキングしません）。「好き」に保存した記事リストと同様に長押しで削除項目の管理も楽々。

9. キャッシュの容量を見ることだけでなく、項目別で管理することもできます。

## 最後に
今後は継続的にバグの改修や機能の拡充はもちろん、**Open** Qiitaなので、年度末あるいは来年のいつかのタイミングでプロジェクトをオープンソース化したいと考えております。