iPad ProでPWAして全画面表示する～最終的に運用でカバー～

![fs.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467051/4601b4c9-9a5e-8ca1-112d-17a5fd9dd087.jpeg)


#おことわり
今回iPad Proにて全画面表示を行う必要があったため、PWAを試してみたが、結構時間がない中での実装だったうえに、iPadがレンタルだったため、細かい検証を行うことができなかった。スクショも取れていないので写真で失礼させていただく。
PWAはまだまだ機能として開発途中な感じがあり、イマイチ挙動が掴めきれなかったので、もしかしたら言葉のニュアンスの違いなど間違ったことを言っている部分があるかもしれません、そういったところは、指摘いただければできるだけ直します。よろしくお願いします。
本来なら記事にするのレベルにも達していない内容だと思いますが、数少ない同じ用途で悩んでいるエンジニアのヒントになればと思い、書くことにしました。なので優しくしてください！w
また、今回先人たちの記事を大量に参考にさせていただいたので、ここで感謝を述べておきたい。

#製作背景
今回ある案件で、展示されたiPadからアプリを介して情報を入力する機能を作成することになった。エンドユーザーが使用するため、必要とされる機能は、

- ネイティブアプリのように全画面表示できる
- 関係のない機能に触らせないようする
- ユーザーの操作でホーム画面に戻らないようにする

など。
swiftを学習する時間はなかったので、ブラウザで全画面表示すればいけるだろうと高をくくって実装を始めたけど、結構クセが強くてハマったので記録しておく。

[参考]https://qiita.com/tmtysk/items/2c5da83feec45b4ee36f
[参考]https://qiita.com/umamichi/items/0e2b4b1c578e7335ba20

#結果
結論から言うと、自動で全画面表示にすることはできなかった。
起動時に画面上部に帯が一本出てしまう状態で、上にスライドすると消える。というところまでしかできなかったので、現場でスタッフさんに朝イチでアプリを起動したら、画面を上にスライドしてもらう。
という運用カバーになってしまった。

#使用した機材
iPad Pro 12.9 インチモデル(第三世代)
iOS 13.2.2


#実装方法

#1.manifest.jsonを設置する
~~short_nameはブラウザのタイトルバーとかに出る名前。~~
nameはアプリ名っぽい。
iconsの192x192に設定した画像がアイコンになるけどこれは罠で、ここだけに書いても反映されない。
後述するタグも埋め込まないといけないらしい。

~~あと余談だが、このshort_nameに設定した名前を後で変更した場合　**safariのキャッシュをクリアしても反映されない**　ここは最後までどうやって更新するのかわからなかった。~~(今思い返すと多分\<title\>の値)
全画面表示にするには、"display"のバリューを"standalone"、もしくは"fullscreen"とすればよさそうだが、手元の環境ではどちらに設定しても挙動は変わらなかった。(キャッシュの影響かもしれない)

```manifest.json
{
  "short_name": "TEST APP",
  "name": "TEST",
  "icons": [
    {
      "src": "./icon.png",
      "type": "image/png",
      "sizes": "192x192"
    },
    {
      "src": "./icon.png",
      "type": "image/png",
      "sizes": "512x512"
    }
  ],
  "start_url": "/start",
  "background_color": "#CDCDCD",
  "display": "standalone",
  "theme_color": "#000000"
}
```

[参考]https://developers.google.com/web/fundamentals/web-app-manifest

#2.Service Workerを有効にする
下記のようなservice-worker.jsを設置する。

```service-worker.js
self.addEventListener('install', function(e) {
  console.log('[ServiceWorker] Install');
});
self.addEventListener('activate', function(e) {
  console.log('[ServiceWorker] Activate');
});
self.addEventListener('fetch', function(event) {});
```

[参考]https://qiita.com/umamichi/items/0e2b4b1c578e7335ba20
#3.headerにタグを入れる
```index.html
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<link rel="apple-touch-icon" href="icon.png" sizes="192x192"/>
<link rel="manifest" href="manifest.json">
<script>
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register("js/service-worker.jｓ").then(function() { console.log('Service Worker Registered'); });
   }
</script>
```
上の二つのタグに関しては、かつてこれらのタグを入れることで透明になったらしいが、[iOS13からblack-translucentgが削除された?](https://forums.developer.apple.com/thread/89471)というような情報もある。
とにかく、手持ちのiPhone7(iOS11.4.1)では効いたが、iPad(iOS13.2.2)ではこれだけで透明にならなかった。
PWA化するとスライドしたときに消えるので、効いているような気もするが挙動がバグっぽい。。
真ん中のiconのリンクタグが、manifestのところで言っていたもの。これを埋め込まないとアイコンが反映されない。
あと、下の二つのタグで、manifest.jsonとservice-worker.jsを読み込んでいる。

#4.ホーム画面に追加からアプリ化する
~~青で消してるのはキャッシュが消えなくてshort_nameが変更できなかったため。~~
これを行うと、ホーム画面にアプリっぽいものが作成される。
![fs3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467051/baa4cce9-51d8-4dc2-81ec-0a4df4438e72.jpeg)

で、ホーム画面に作成されたアイコンから起動すると以下のような画面になる

![fs2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467051/3c49fbef-b701-b336-4b4f-dce745fac69c.jpeg)

この上の白いバーの存在が謎。。。
これについては、何かタグが入っているのではないかと思い、document.body.clientHeightで出力してみたが、本来の高さが返ってきたのでおそらくsafari側で入れられている何かかと思われる。
この状態から一度上にスライドすれば以降このバーは消えるのだが、そもそもkioskとしての運用なので、スライド操作自体を無効化したい。

#5.一度だけ上方向へのスライドを有効にする。
[参考]https://gist.github.com/violetyk/5343883

```js
	function no_scroll(){
		document.addEventListener('touchmove', handleTouchMove, { passive: false });
	}
	function scroll(){
		document.removeEventListener('touchmove', handleTouchMove, { passive: false });
	}
	let start_pos = 0;
	$(window).scroll(function(e){
	  var current_pos = $(this).scrollTop();
	  if (current_pos > start_pos) {
	    no_scroll();
	  }else{
			// 
		}
	  start_pos = current_pos;
	});
```
ここからが力業。アプリ起動後一度だけ上方向へのスクロールを許すようにする。
これで一応全画面表示ができるようになった。
スクロールの復帰関数も用意してあるのは、アプリを再起動すると上の謎のバーが再び出現するため、画面内に隠しボタンを設置し、そこを押すと再びスクロールできるように作ったため。
そしてこのスクロール、これもなかなかハマりポイントで、古い記事の方法とかだと動かなかったりする。
[参考]https://qiita.com/yukiTTT/items/773356c2483b96c9d4e0

#アクセスガイドを設定してホーム画面に戻れないようにする
設定からアクセスガイドをオンにする。
ホームボタンがある機種はホームボタンを、ない機種はサイドの電源ボタンを三回押しすると起動する。
これで完全なフルスクリーンになる。

こちらの機能は、タッチ不可の領域を設定したりできるが、設定した範囲はグレーになるので、見栄えがあんまりよろしくない。

[参考]https://qiita.com/ousaan/items/5464f99bf15675ccc84b

<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/nP8yCHhBSM">pic.twitter.com/nP8yCHhBSM</a></p>&mdash; たくみ@スカジャンのエンジニア (@hatt_takumi) <a href="https://twitter.com/hatt_takumi/status/1227904113419018240?ref_src=twsrc%5Etfw">February 13, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


#他に試したことなど
#フルスクリーンAPIを使う
フルスクリーンAPIというのがある。
こちらも試してみたが、自動で全画面にするっていうのが無理で、何かしらのユーザーの操作をトリガーにしないといけないっぽい。(セキュリティ的に？)
かつ、全画面にしても左上に大きなxボタンが出るので、ちょっと今回の用途には合わなかった。
![fs4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467051/6aecfbbc-fe62-3570-2f97-e2538ae064e9.jpeg)

[参考]https://qiita.com/annnews23/items/728a87a256cd0cf6e3a5
[参考]https://qiita.com/uzuki_aoba/items/ea7f35bc2833dd58b9ef


#そもそもタブレットで全画面表示するのは難しい
PCの場合、chromeにkioskモードというのがある。
これを使えば全画面表示で最前面に表示されkioskとして使用できる。
(タッチデバイスの場合はこまごま他の設定が必要だが。。)
PCはキーボードというインターフェースがあるのでf11で一発で復帰できるが、
そもそもタブレットは物理的なインターフェースが少ない。
全画面表示で操作不能となるような事態を避けるため、メーカー側でそう簡単には完全な全画面にならないように設計していると思われる。
案件状況によっては、タッチ機能の付いていないモバイルディスプレイで全画面表示するように製作したほうがはるかに簡単なので、こだわりがなければこちらに切り替えることをお勧めする。