ドシロウトがPWAしてみた

## ０．初めに

私はエンジニアではないただのドシロウトです。

PWAを少しだけ勉強しており、実際に自分のAndroidタブレットで動かしてみたくなりました。

PWAの説明は詳しく書かれている記事がありましたので以下をご参照ください。

[・いまさら聞けないPWAとAMP](https://qiita.com/edwardkenfox/items/4c0b9550ffa48c1f0445)

個人的にはアプリみたいにAndroidタブレットのホーム画面からアイコンタップしてアプリっぽく使いたいなぁという程度です。

## １．作ったもの

以下の動画の通りです。カレンダーで日付選択すると７日前の日付を算出するだけです。

[・7日前計算](https://youtu.be/l67878PiM6w?t=35)

デートピッカーは以下のJSライブラリのJS本体＋CSS2本をダウンロードしてそのまま利用しています。

[・patrickkunka/datepicker](https://github.com/patrickkunka/datepicker)

## ２．使用した環境

PWAはHTTPSでないと動かないのでホスティング先は[Bitbucket](https://bitbucket.org)にしました。Bitbucketでの静的ウェブサイト公開については以下の記事を参考にしています。

[・Bitbucketで静的ウェブサイトを公開する](https://qiita.com/naoqoo2/items/e659d83074a269f3ae74)

ローカル側環境はクラウドIDEの[CODENVY](https://codenvy.com/)を使いました。

CODENVYからBitbucketへのデプロイ方法については以下の別記事に書いています。

[・ドシロウトがCloud IDEからGitHub PagesとBitbucketに静的ウェブサイトを公開してみた](https://qiita.com/basictomonokai/items/1c3fc823f687de90f4d6)

## ３．使用したファイル

使用したファイルは以下です。

![pwabitbucket.png](https://qiita-image-store.s3.amazonaws.com/0/35574/b476e895-887f-3882-13df-6743ddd5f3ee.png)


| № | ファイル名 | 説明 |
|:-:|:-:|:-:|
| 1 | datepicker.js | カレンダーライブラリ  |
| 2 | demo.css | datepicker.js用CSS |
| 3 | styles.css | datepicker.js用CSS |
| 4 | icon.png | ホーム画面用アイコン |
| 5 | day7pwa.html | HTML本体 |
| 6 | manifest.json | PWA用マニフェスト |
| 7 | service_workerday7.js | サービスワーカ  |

№４のアイコンはフリーのアイコン配布サイト[Icons8](https://icons8.jp/)のアイコンを192×192にサイズ調整しただけです。

№５～７ついては以下の記事を参考に自分で用意したものです。

[・PWAをもっと簡単に初めてみる](
https://qiita.com/poster-keisuke/items/6651140fa20c7aa18474)

[・PWA形式のWebサイトを構築してAndroidスマートフォンにインストールする](
https://qiita.com/OMOIKANESAN/items/5b23fa8ea9ea0d181df5)

[・シンプルなPWAサンプルここに置いておきますね](
https://qiita.com/kazaoki/items/e93b88556fcd05d28ddc)

## ４．コード

自分で用意したファイルはHTML、JSON、JSファイルの計３本です。


まずはHTMLファイル。通常のHTMLと異なる点は、マニフェストJSONとserviceWorkerの設定を記述してるくらいだと思います。


```HTML:day7pwa.html
<html>
<head>

  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">

<!-- マニフェストJSON -->
<link rel="manifest" href="manifest.json">


<link rel="stylesheet" href="demo.css"/>
<link rel="stylesheet" href="styles.css"/>




<script src="datepicker.js"></script>

<title>７日前計算</title>
</head>

<body>
<div class="field">
  <h1>７日前計算機</h1>
  <p></p>
  <input id="indate" name="date" readonly placeholder="タップ→日付選択"/>
  <p></p>
  <div>結果</div>
    <input id="outdate" name="outdate" readonly  placeholder="7日前の日付"/>
</div>


<script>

// serviceWorkerの設定

    if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('service_workerday7.js').then(function(registration) {
        console.log('ServiceWorker registration successful with scope: ', registration.scope);
    }).catch(function(err) {
        console.log('ServiceWorker registration failed: ', err);
    });
    };


// datepicke.js用の指定
var input = document.querySelector('input[name="date"]');

var picker = datepicker(input);

// 入力、結果エリア
var indate = document.getElementById('indate');
var outdate = document.getElementById('outdate');

function get7day() {
  // 7日前計算関数
  console.log(indate.value);
  var caldate = new Date(indate.value);
  console.log(caldate.getTime()-(7*24*60*60*1000));
  var caldate7 = new Date(caldate.getTime()-(7*24*60*60*1000));
  console.log(caldate7);
  var calyear7 = caldate7.getFullYear();
  var calmonth7 = ('0' + (caldate7.getMonth()+1)).slice(-2);
  var calday7 = ('0' + caldate7.getDate()).slice(-2);
  var strdate7 = calyear7 + '-' + calmonth7 + '-' + calday7;
  console.log(strdate7);
  outdate.value = strdate7;

};


// イベント設定
indate.addEventListener( 'change' , get7day , false );



</script>

</body>
</html>

```

次にマニフェストJSONファイルです。

* short_name : アイコンの名前
* name: ローディング画面に出る名前
* start_url : よく分かってないがindex.htmlではうまく行かなかった
* icons : アイコンのファイル名、サイズ、種類


```javascript:manifest.json
{
    "short_name": "７日前",
    "name": "7日前計算PWA版",
    "display": "standalone",
    "start_url": "day7pwa.html",
    "icons": [
        {
            "src": "icon.png",
            "sizes": "192x192",
            "type": "image/png"
        }
    ]
}
```

最後にサービスワーカJSです。よくわかってませんがCACHE_NAMEを固有の名前にしてurlsToCacheにHTML,JS,CSSファイルをフルパスで指定しました。

```javascript:service_workerday7.js
// キャッシュファイルの指定
var CACHE_NAME = 'pwa-day7pwa2-caches';


var urlsToCache = [
    "https://aaaaaa.bitbucket.io/day7pwa/",
    "https://aaaaaa.bitbucket.io/day7pwa/day7pwa.html",
    "https://aaaaaa.bitbucket.io/day7pwa/datepicker.js",
    "https://aaaaaa.bitbucket.io/day7pwa/demo.css",
    "https://aaaaaa.bitbucket.io/day7pwa/styles.css"
];

// インストール処理
self.addEventListener('install', function(event) {
    event.waitUntil(
        caches
            .open(CACHE_NAME)
            .then(function(cache) {
                return cache.addAll(urlsToCache);
            })
    );
});

// リソースフェッチ時のキャッシュロード処理
self.addEventListener('fetch', function(event) {
    event.respondWith(
        caches
            .match(event.request)
            .then(function(response) {
                return response ? response : fetch(event.request);
            })
    );
});
```


## ５．まとめ

こんな感じで動画の通り、プチアプリ感覚で利用できます。

なかなか便利だと思いました。


以　上