5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Flutterで手軽にPWA ~2020年末の対応状況

Last updated at Posted at 2020-12-17

この記事は、
softdeviceのみんなでゆるく記事を書く。 Advent Calendar 2020
の12/17の記事として公開しています。

はじめに

最新のFlutterWebでは、標準でPWAに対応しました。

Flutterはモバイルアプリ用フレームワークなので PWAと相性が良さそうです。しかも、どちらもGoogleが推進している技術なので、今後にも期待できます。
個人的には、1つのコードで、Web(PWA)、Android、iOS、デスクトップアプリを開発できることは、フレームワーク選定において大きなアドバンテージになるので、気になっていました。

ということで、FlutterWeb標準でどういう機能が追加されたのか、触りながらみていきます。

PWAとは

Googleなどが提唱している概念で、Webサイトをあたかもネイティブアプリのように利用できる技術です。PWAに対応することで、ネイティブアプリのようなUXを提供することができます。
詳しい定義については、下記の解説をご覧ください。

プログレッシブウェブアプリの紹介 -MDN web docs
What makes a good Progressive Web App? -Google web.dev

MDNとGoogleで少し定義が違いますが、ホーム画面に追加オフラインキャッシュプッシュ通知 の3つが提供されれば、PWAと言って良さそうです。

FlutterでPWAを試すには

PWA対応で必要な手順はそんなに多くありません。
しかも、ほとんどFlutterが自動でやってくれます。

PWA対応手順

  1. WebサイトのHTTPS化
  1. ホーム画面に表示するアイコン作成・設置
  2. WebアプリManifest(manifest.json)の作成・設置
  3. Service Workerの作成・設置

1 はHTTPS化されているホスティングサービス Firebase Hosting を利用すると手軽です。
2〜4 は、少し前まで手動で行う必要があったのですが、現在は要らなくなりました。
Flutterをビルドすると自動で作成・設置されます。

ということで、こちらの手順を進めると、PWAを試すことができます。
【FlutterWeb】Firebase Hosting でWebアプリを公開する - Qiita

PWAを触ってみる

公開したWebアプリを開いてホーム画面に追加すると、アプリアイコンが設定されて全画面表示で起動しました。
起動時の読み込みも早く、オフラインにしても動作します。
さらに、MacのChromeでも、Webアプリとして追加できました。

▼Android
android_pwa2.gif
▼iOS
ios_pwa2.gif
▼Mac Chrome
mac_pwa2.gif

簡単に解説

FlutterWebを有効にすると、Webフォルダが追加されます。
このフォルダがビルドのテンプレートとなります。
スクリーンショット 2020-12-17 12.40.07.png

iconsフォルダ

ホーム画面に追加した時のアイコンです。
スクリーンショット 2020-12-17 12.45.05.png

manifest.json

ホーム画面に追加するための設定ファイル。スプラッシュ画面にも反映されます。
現時点では、AndroidとChrome用です。

manifest.json
{
    "name": "flutter_web",
    "short_name": "flutter_web",
    "start_url": ".",
    "display": "standalone",
    "background_color": "#0175C2",
    "theme_color": "#0175C2",
    "description": "A new Flutter application.",
    "orientation": "portrait-primary",
    "prefer_related_applications": false,
    "icons": [
        {
            "src": "icons/Icon-192.png",
            "sizes": "192x192",
            "type": "image/png"
        },
        {
            "src": "icons/Icon-512.png",
            "sizes": "512x512",
            "type": "image/png"
        }
    ]
}

manifestの変更は、App Manifest Generatorというサイトが便利です。
アイコンのサイズ変換とmanifest.jsonの生成が簡単にできます。

各要素については、下記のリンクが参考になります。
Web App Manifest - MDN web docs
Add a web app manifest - Google web.dev

index.html

manifest.jsonのリンク、Service Workerの設定が追加されています。
また、iOS用の設定もmetaタグで追加されています。
将来的には、iOSでもmanifest.jsonをサポートするようです。

index.html
<!DOCTYPE html>
<html>
<head>
  <!--
    If you are serving your web app in a path other than the root, change the
    href value below to reflect the base path you are serving from.

    The path provided below has to start and end with a slash "/" in order for
    it to work correctly.

    Fore more details:
    * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
  -->
  <base href="/">

  <meta charset="UTF-8">
  <meta content="IE=Edge" http-equiv="X-UA-Compatible">
  <meta name="description" content="A new Flutter application.">

  <!-- iOS meta tags & icons -->
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
  <meta name="apple-mobile-web-app-title" content="flutter_web">
  <link rel="apple-touch-icon" href="icons/Icon-192.png">

  <!-- Favicon -->
  <link rel="icon" type="image/png" href="favicon.png"/>

  <title>flutter_web</title>
  <link rel="manifest" href="manifest.json">
</head>
<body>
  <!-- This script installs service_worker.js to provide PWA functionality to
       application. For more information, see:
       https://developers.google.com/web/fundamentals/primers/service-workers -->
  <script>
    if ('serviceWorker' in navigator) {
      window.addEventListener('flutter-first-frame', function () {
        navigator.serviceWorker.register('flutter_service_worker.js');
      });
    }
  </script>
  <script src="main.dart.js" type="application/javascript"></script>
</body>
</html>

ネイティブアプリとPWAの描画エリアの比較

iOSの場合、ネイティブアプリとPWAで描画エリアが違いました。
ステータスバーを黒→透明に変更して試してみます。

index.html
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">

safearea2.png
▲ネイティブアプリとPWAの比較 (青が描画エリア、水色がSafeArea)

・描画エリアがステータスバーまで伸びていない。
・セーフエリアが正しく取得できていない。

ネイティブアプリのような見た目にしたい場合は、少し工夫が必要です。

Service Worker

index.htmlには、Service Worker というものが追加されていました。

Service Workerは、ブラウザがWebページとは別にバックグラウンドで実行するスクリプトです。
PWAにおいて、オフラインキャッシュプッシュ通知を提供します。
Service Workers: an Introduction - Google Developers

オフラインキャッシュは Android / iOS ともにできていたので、正常に動作しているようです。
プッシュ通知は、Firebase Cloud Messaging と合わせて使うようですが、iOS14ではまだPWAのプッシュ通知がサポートされておらず、Appleの対応を待つしかないようです。

まとめ

iOSのプッシュ通知以外は、FlutterWeb標準でPWAの要件を満たしていました。
FltterWeb自体のパフォーマンスが高く、Androidでは見た目も操作感もネイティブアプリと遜色ないので、小規模なアプリならPWAで充分やっていけそうです。

iOSではAppleがPWA推進派ではないので、どうしてもネイティブアプリと違う部分が出てきます。時間が解決してくれるはずなので、無理にネイティブアプリに合わせず、割り切るのも手かもしれません。

機能面では、Flutterパッケージの中にはまだFlutterWebに対応していないものがあるので、事前に調査が必要です。
また、PWA自体にまだ制約があるので、Android と iOS の対応状況をみながら、機能を見極める必要があります。

PWAの現状をについては、下記の記事が参考になりました。
PWA 入門 〜iOS SafariでPWAを体験するまで〜 2019年7月更新 - Qiita

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?