「ホーム画面に追加」からはじめる『PWA(Service Worker)』

Android ChromeでService Workerが使えるようになり、徐々に盛り上がりを見せそろそろ使ってみても良いんじゃ・・・という匂いも感じ始めています。
**ブラウザプッシュ**での通知や**キャッシュ**などの機能に**Service Worker**の注目が集まりがちですが、これらの実装はかなり複雑でやっかいです。

その中でも一番実装が簡単なService Worker(?)が**ホーム画面に追加**の機能です。
この機能はService WorkerのJSは１文字書く必要がないので、Service Workerの実装を始める前にやっておくのも良いと思います。

## 実際に実装してみると、下からにゅるっと出てきます

[![ホーム画面に追加の例](https://qiita-image-store.s3.amazonaws.com/0/7132/04fe93c4-d967-bb89-5df3-a3e20f0e03c7.png)](https://gamy.jp/)


## 条件
* HTTPS接続（または localhost）
* Android Chrome 42以上

が必要です。SSLは [https://letsencrypt.org/](https://letsencrypt.org/) で無料で入れられるので入れましょう。


## `manifest.json`を作成

```json:/manifest.json
{
    "name": "GAMY（ゲーミー）- みんなのゲーム攻略メディア",
    "short_name": "GAMY攻略",
    "icons": [
        {
            "src": "/static/img/icon/144.png",
            "sizes": "144x144",
            "type": "image/png"
        }
    ],
    "start_url": "/",
    "display": "standalone",
    "theme_color": "#e91e63"
}
```

Chrome拡張のmanifest.jsonとだいたい一緒だけどiconsまわりとか違うので注意

| 名前 | 説明 |
|:----|:------------|
| name | アプリケーション名 |
| short_name | ホーム画面で表示される省略名 |
| icons | アイコン |
| start_url | アプリを開いたときのURL |
| display | 表示形式 |
| theme_color | テーマカラー |

``display``はiOS safariの`apple-mobile-web-app-capable`みたいな使い方ができます。
`standalone`を指定するとChromeからアドレスバーがなくなりネイティブっぽい表示ができます。

``theme_color``を指定するとAndroidステータスバーの色が変わる。

manifestファイルの詳細はここに [https://www.w3.org/TR/appmanifest/](https://www.w3.org/TR/appmanifest/) 


## `manifest.json`をHTMLに追加

headタグの中にコードを記述してください。

```html:/index.html
<link rel="manifest" href="/manifest.json">
```

この設定で`apple-touch-icon`系がmanifest.jsonの記述を優先するようになります。


## `serviceWorker.js`を作成

```js:/serviceWorker.js
self.addEventListener('fetch', function(event) {
});
```
~~空っぽでOK~~
何かしらfetchイベントを書かないとダメになったそうです。

```
参考 (1): https://amymd.hatenablog.com/entry/2017/10/12/001612
参考 (2): https://stackoverflow.com/questions/44886248/add-to-home-screen-web-app-install-banner-not-showing-up-in-my-web-app-and-show
```


## `serviceWorker`の登録

JSに下記のコードを貼り付けてください。

```html:/index.html
<script>
window.addEventListener('load', function() {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register("/serviceWorker.js")
      .then(function(registration) {
        console.log("serviceWorker registed.");
      }).catch(function(error) {
        console.warn("serviceWorker error.", error);
      });
  }
});
</script>
```

ServiceWorkerにはscopeがあり、serviceWorker.jsの位置でscopeが決まります。
なのでserviceWorker.jsはドメイン直下に配置した方が楽です。


## 確認方法
ちょっと面倒ですが、サイトを1週間で2回表示したときに表示されるという仕様です。
なので１度目は表示されず、別のセッションでもう一度アクセスしたときにホーム画面に追加ボタンが表示されます。

### ホームに追加するとこんな感じ

![ホーム画面に追加した](https://qiita-image-store.s3.amazonaws.com/0/7132/daa21361-e3f0-558c-9a59-88d081831d9d.png)


## おわり
Service Workerのコードは１文字も書きませんでしたが、これでService Workerを使いはじめる準備が整いました。

実際に動作しているのが見たい場合は [https://gamy.jp/](https://gamy.jp/) で実装しているのでAndroidでアクセスしてみてください。



こういうの良くやってるけど、これをブラウザ側でやってくれて楽ができる。
![iphonehomebtn01.jpg](https://qiita-image-store.s3.amazonaws.com/0/7132/0b4250e0-7c4c-3365-39ba-698de08a276d.jpeg)


### プッシュ通知編も書きました。
[http://qiita.com/narikei/items/0f26b30d347ae19d9559](http://qiita.com/narikei/items/0f26b30d347ae19d9559)