booklista tech blog

booklista のエンジニアリングに関する情報を公開しています。

App Storeで3位になったアプリをFlutterでつくっている話

自己紹介

はじめまして
株式会社ブックリスタでスマートフォンアプリエンジニアをしている藤井と申します。

まだまだスマートフォンアプリに関しては始めたばかりの弊社ですが、界隈では有名になりつつあるOshibanaというアプリを開発しています。
Oshibanaってどんなアプリなのか簡単に説明すると「推しを常に身近に感じて推し活と人生を豊かにしてくアプリ」です。
ご存知でない方はぜひとも、一度手に取ってもらえるとありがたいです。

Oshibana

※今はiOS版だけになります。

Flutter について

さて、冒頭でも紹介したOshibanaですがFlutterを採用して開発しております。

FlutterはGoogleが提供するDart言語を使用したアプリケーションフレームワークです。
 ※アプリケーションフレームワークとは、アプリの開発を支援するために作られたライブラリのこと。

現在はモバイルアプリケーションのフレームワークとして有名ですが、Webアプリ、デスクトップアプリ(Windows,Mac,Linux)などのアプリも作ることが可能です。
今後はFlutterができればどんなアプリも作れる時代が来ることでしょう。

ただ実際にプロジェクトで採用する際に問題となるのが、言語がDartという点。
普通に使ってると学ぶことはなく、過去にはワーストランキングで1位になるという不名誉1も持っています。
私も最初は難しいのかなと思っていたのですが、実際に携わってみると言語としてはそんなに難しいものではないと感じました。
また人気も、今はFlutterの人気に伴い急上昇2をしています。

難しいと思わなかった理由

  • 関数や処理の書き方もJavaやCを学んだ人ならすぐに理解できる
  • 公式サイトに色々なパッケージが用意されており、一般的なiOS、Andoridの機能はDartのみで実現できる
  • 画面を作成する上でホットリロードがかなり便利で、ビルドし直しの手間を減らすことができる
  • 画面を作成するための基礎的なWidgetについては日本語の資料がいっぱいWebに存在している
  • Flutterで実現できない場合でも、KotlinやSwiftを使って処理ができる

でもやっぱり、デメリットもあります

  • 画面を生成するためのWidgetの組み合わせは慣れないと配置が難しい
  • 状態管理がいっぱいありすぎて何がベストプラクティスなのか迷ってしまう
  • iOSアプリっぽく作ろうとすると標準のマテリアルデザインを変える必要がある
  • ちょっと複雑なことをしようとすると、英語などの資料を読む必要がある

パッケージ紹介

Flutterはいろいろなパッケージがあり、公式サイトで管理されてます。
色々なパッケージがあり大変便利なのですが、前述したデメリットで挙げた通り日本語説明を書いてくれているWebサイトがないパッケージも多数あります。 せっかくなのでそういったパッケージを紹介します。

https://pub.dev/packages/background_fetch

background_fetchというパッケージです。
どんなパッケージかというと、アプリがバックグランドにいっても処理を行う機能を追加するためのものになります。

Oshibanaではこのバックグランド処理を使って、通知用のデータ作成やクリアを行っています。

Webで検索するとworkmanagerがよく引っかかるのですが、私の場合、ひとまず手順書どおり実装してもXcodeを使ったBackgroundFetchのテストで動作が確認できませんでした。
その後、実機で確認してみてもやはり動作していませんでした。
そのため、色々検討した結果background_fetchの導入をしました。
また、background_fetchの方が導入時に必要な設定が少なめになっており、個人的にはおすすめです。

導入方法

パッケージのpubspec.yamlに次のように記入を追加します。

  dependencies:
   background_fetch: ^1.0.2

現時点でOshibanaアプリはiOSだけの対応ですので、記載もiOSだけに絞って記載します。

 まず、Runner配下のinfo.plistに次の記述を追加します。

 <key>BGTaskSchedulerPermittedIdentifiers</key>
    <array>
        <string>XXX.YYYYYYYYY.fetch</string>
    </array>
    <key>UIBackgroundModes</key>
    <array>
        <string>fetch</string>
        <string>processing</string>
    </array>

以上で準備は完了です。

あとは次のコードをmain.dartのinitStateあたりで呼び出せば完了です。

    int status = await BackgroundFetch.configure(BackgroundFetchConfig(
        minimumFetchInterval: 30,
    ), (String taskId) async {  

   //ここにバックグラウンドで実行したい処理を追加する

      BackgroundFetch.finish(taskId);
    }, (String taskId) async {  
      BackgroundFetch.finish(taskId);
    });

公式ですと、BackgroundFetchConfigに対していろいろな引数を設定していますが、minimumFetchInterval以外はAndorid用の設定になります。
そのため、iOSでの運用であればその他は設定する必要がありません。
また、minimumFetchIntervalの設定値はiOSの場合15分以上に設定する必要があります。

さいごに

ここまで読んでいただき、ありがとうございました。
ブログ作成ということ自体が初めてでしたので拙い内容となっておりますが、皆様に読んでためになることを今後も記載していけるよう日々精進いたします。