書籍メモアプリ「PickBook」をFlutterでリリースした【個人開発】

# 概要

* アプリの説明
* 作ろうと思ったきっかけ
* アプリの機能について
* リリース準備について
* 現状・今後実現していきたいこと、意気込み


Flutter頑張ってます[tomo](https://twitter.com/tomoDev_)と申します。
自分と同じようにアプリを作る方またこれからアプリを作りたいと思っている方に向けて何かのヒントになれば嬉しいです！


# リリースしたアプリについて


https://play.google.com/store/apps/details?id=com.tomoyaNakano.PickBook

PickBookという本の記録を簡単にできるアプリになります。

**特徴**

* バーコードで簡単に書籍登録
* テキスト認識を利用して写真を取るだけで簡単にメモ

こちらのアプリは今年の初めの方にリリースしました。（~~Qiita記事書くのサボった~~）
数字伸びてないので供養気味（PR気味）に紹介しようと思います。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551776/a11ce3e0-1f34-aea0-15a7-950611aa6de7.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551776/73994602-38aa-c6c6-1ae2-fd21d10421ce.png)

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551776/25cadf62-aec6-a376-90a3-6df1b38087e1.png)


# このアプリを作ろうと思ったきっかけ

僕はよく電車の中で本を読むのですが本の内容をちょっとメモしたい時に手間がかかるという課題がありました。
「ペンで書くのは煩わしい」
「本をひらきながらスマホでテキストを打ちにくい」
などなど。

電子書籍にすれば解決はしますが、紙の書籍の方が好きなのでこの課題を解決できるようにアプリを作ろうと思ったのがきっかけです。

# アプリの機能について

このアプリはFlutterで作成し、アーキテクチャはChangeNotifier + Providerで構築しています。
DBはローカルのSQliteを使用しました。

このアプリの主な機能は二つあります

* バーコードで簡単に書籍登録
* テキスト認識を利用して写真を取るだけで簡単にメモ

この二つの機能の実装についてコードを交えつつ説明していきます。


## バーコードで書籍登録

このアプリではバーコードを読み取るだけで書籍登録ができるようになっています。
コンセプトとして簡単な操作だけで使えるようにするという目的があったので、この機能を実装しました。

**実装方法**
実装自体はとてもシンプルで簡単に行うことができました。
実装手順は以下のようになっています。

* packageを利用してバーコードをスキャンしISBNコードを取得
* Google Books APIに取得したISBNコードを投げる
* 結果を元にDBに保存



### バーコードスキャン
バーコードのスキャンには`barcode_scan`という以下のパッケージを利用しました。
[barcode_scan | Flutter Package](https://pub.dev/packages/barcode_scan)

とても簡単にバーコードのスキャンが可能になります。
以下コードになります

```dart:BookModel.dart

  Future<void> scanBook() async {
    try {
      ScanResult result = await BarcodeScanner.scan();
      //キャンセルを弾く
      if (result.type != ResultType.Cancelled) {
        //Repository層へ結果を渡す
        final book = await _bookRepository.fetchBookfromIsbn(result.rawContent);
        _scanedBook = book;
      } else {
        throw ('canceled');
      }
  }
```
この処理はBookを管理するViewModelの一部の処理です。
バーコードスキャンを行い、その結果をRepository層に渡しています。

やっていることは非常にシンプルで、

```dart
ScanResult result = await BarcodeScanner.scan();
```
この処理を行うだけで、カメラが起動しバーコードをスキャンすることができます。
非常にシンプルですね。
あとは`result.rawContent`が実際のIsbnコードを持っているので、それを渡してあげるだけです


### Google Books APIへリクエストを投げる

書籍検索はGoogle Books APIを利用しました。
[Google Books API](https://developers.google.com/books/docs/v1/using)

利用のための登録等も特になく簡単に書籍検索が行えます。
より詳しい利用法に関しては以下の記事が参考になるかと思います。
[Google Books API からJSONデータを取得してjQueryで処理する](https://qiita.com/TakeshiNickOsanai/items/2d9c30cedcba21f36669)

以下コードになります


```dart
class BookRepository {
  BookAPI get _bookAPI => BookAPI();

  Future<Book> fetchBookfromIsbn(String isbn) async {
    final result = await _bookAPI.fetchBookfromIsbn(isbn);
    if (result == null) {
      throw ("book not found");
    }
    final node = json.decode(result);
    return Book.fromJsonResult(node['items'][0]['volumeInfo']);
  }
}

class BookAPI {
  Future<String> fetchBookfromIsbn(String isbn) async {
    final String url = 'https://www.googleapis.com/books/v1/volumes?q=isbn:';
    final result = await http.get(url + isbn);
    return result.body;
  }
}

```

こちらも非常にシンプルでバーコードスキャンで渡ってきたIsbnコードをGoogleBooksAPIに指定して投げてあげると書籍のデータが返ってくるのでそれを用意したオブジェクトに変換して返しています。

中身のデータに関しては以下をみてみてください。

https://www.googleapis.com/books/v1/volumes?q=isbn:9784274068560





## テキスト認識で簡単にメモ
テキスト認識に関してはFirebase MLで実装しました。
特に難しいことはなく（なかったはず）実装できました。

以下実装手順です

* ImagePickerで画像を取得
* 画像を認識させてテキストに起こす


### ImagePickerで画像を取得

`image_picker`という以下のパッケージを利用しました
[image_picker | Flutter Package](https://pub.dev/packages/image_picker)

こちらのパッケージに関してはFlutter触られてる方なら一度は使ったことあるんじゃないかなと思います。

```dart
final pickedFile = await picker.getImage(source: ImageSource.camera);
```

これでカメラが起動し画像を取得できます。簡単ですね。

###Firebase MLでテキスト認識させる
テキスト認識はFirebase MLを利用しました。以下のパッケージを利用することでFirebase MLの画像認識を使うことができます。
[firebase_ml_custom | Flutter Package]()


事前に学習されたモデルがあるのでこれを使えば、自分で学習させることなく数行のコードで実装することができました。Firebase便利！

以下コードになります

```dart
Future<String> _scanImage() async {
  //Firebase MLのインスタンス生成 cloudDocumentTextRecognizerは文字認識用
  final DocumentTextRecognizer _documentTextRecognizer =
      FirebaseVision.instance.cloudDocumentTextRecognizer();
  //image_pickerで画像を取得
  final pickedFile = await picker.getImage(source: ImageSource.camera)
  // 画像を設定
  final FirebaseVisionImage visionImage = FirebaseVisionImage.fromFile(pickedImage)
  // テキスト認識させる
  final VisionDocumentText _scanResults = await _documentTextRecognizer.processImage(visionImage);
  // 認識結果
  return _scanResults.text;
}
```

これだけで画像を元にしたテキスト認識が可能になります。しっかり文字が目で確認できる画像であればテキスト認識を精度高くしてくれます。
あとはこれをRichTextに入れ、コピー可能にしてフォームに入力させる形にしました。
UIは以下のように実装しています。

※ 実際の書籍の画像を利用しているので著作権保護のためにぼかしを入れてます
![в кривых.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551776/2d121aff-5091-d205-3f7a-c860c6daf31d.png)

これでテキストをなぞってコピーし、以下のフォームにペーストするだけで本の内容がメモできます！やった！


## リリース準備について

リリース準備は以下のことを行いました。

* アプリアイコン・スクリーンショットの作成
* ストア申請


### アイコン・スクリーンショット画像の作成

**アイコン**

アイコンやスクリーンショット画像の作成はいつも[Canva](https://canva.com)というデザインツールを利用して作成しています。

アイコンは以下のようにしました。今回は特に何も考えず作ってしまったので、いまいちなアイコンになってます。（いつか直したい）
アプリアイコン作成時のテンプレとかあると個人開発する上で便利そう。

<img width="200" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551776/9be79d07-78fd-a00b-a37f-a97c06e70835.png">


あとはこれを`flutter_launcher_icons`というパッケージを利用して`pubspec.yaml`で指定してあげて完了です。


**スクリーンショット**

スクリーンショット画像も同じようにCanvaを利用して作っていますが、スマートフォンのモックアップ画像の作成だけはFigmaというデザインツールを使っていつも作成しています。

スマートフォンの外枠のみのテンプレートが落ちてるので、アプリのスクリーンショットをとってその枠にはめるだけでいい感じのモックアップ画像ができます。
あとはそのモックアップ画像をCanvaに入れてテキストや背景色を整えて完成です。割と簡単にそこそこの画像が作成できます。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551776/a11ce3e0-1f34-aea0-15a7-950611aa6de7.png)

### ストア申請

今回はAndroid版のみの配信になるので、Google play consoleの登録準備を行いました。
これまで何回かアプリをリリースしてきましたが、いまだになれません。
以下のページとかをみて調べながら審査の提出をしています。


https://flutter.dev/docs/deployment/android



## 現状・今後の意気込み

アプリをストアに登録して3ヶ月ほどたちましたが、いまだに全然ダウンロードされていません。
こういうツール系のアプリは競合もたくさんいるのでしっかりPRだったりASO対策をしないとインストール数を伸ばすのは難しいですね。

ただ、今まで作ったアプリは自分が継続的に使うことはなかったんですが、今回は僕が課題に感じていることに対するアプリなので自分でもよく利用していて、非常に便利だなと感じています。

もし僕と同じような課題を抱えている方がいましたら是非「 PickBook 」をダウンロードして使ってみてください！

https://play.google.com/store/apps/details?id=com.tomoyaNakano.PickBook

個人開発でアプリを作る時はいつもアイデアから考えていましたが、今回のアプリで改めてユーザーの課題からしっかり考えてアプリのアイデアを作るということはとても大切だと感じました。
また、その課題が自分が抱えている物ならなお良いです。今回のように最悪インストールが伸びなくても自分が使える物になるので。
これからも個人開発する際は自分の身の回りに課題と感じていることはないかということを日々探しながらアプリを作っていきたいです！

## 最後に
今回はFlutterで作った本の記録アプリを紹介しました！
コードとかで間違っているところがあればコメントで教えてください！
また感想などをコメントいただけると嬉しいです！

今後ともFlutterを使った開発頑張っていくのでよろしくお願いします！
Flutterに関する情報発信頑張ってしていくので、[Twitter](https://twitter.com/tomoDev_)のフォローもしてね！