LoginSignup
18
19

More than 3 years have passed since last update.

PWAのmanifest.jsonを動的に生成する

Posted at

iOSにおける問題

WebサイトをPWAに対応させる
上記の対応を行ったサイトで実際にホーム画面追加したアプリを起動してみると、Andoroidでは問題なく利用できましたが、iOSではログイン画面が開きました。
セッション情報をLocal Storageに保存していた場合に、AndroidではLocal Storageの情報がブラウザと共有されるのに対し、iOSでは共有されないようです。

再度ログインし直せばそれで済む問題ではありますが、ユーザーにとっては2度手間になってしまいます。

start_urlにパラメータを付加したい

上記の問題を解決するために、ホーム画面にアイコンを追加するタイミングでURLパラメータにセッショントークンを追加してログイン情報を引き継ぐことにしました。
そのために、manifest.jsonの内容を動的に作成し、start_urlにパラメータを付加することを検討しました。

linkタグを書き換えられるようにする

まず、manifest.jsonを読み込むためにhtmlに追加したlinkタグを次のように書き換えます。

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

index.html
<link rel="manifest" id="my-manifest" />

これで、次のようにしてmanifest.jsonを置き換えられるようになります。

document.querySelector('#my-manifest').setAttribute('href', '/manifest.json');

manifest.jsonを動的に生成する

次のようなfunctionを用意しておき、セッショントークンを生成したタイミングで呼び出すことでセッション情報を付加したURLを作ることができました。

manifest.js
var setManifestURL = function (token = null) {
    var myUrl = window.location.href;
    var startUrl = token ? myUrl + "?token=" + token : myUrl;

    var manifest = {
      "name": "Sample Application",
      "short_name": "SMPL APP",
      "theme_color": "#2196f3",
      "background_color": "#2196f3",
      "display": "standalone",
      "start_url": startUrl,
      "icons": [
        {
          "src": myUrl + "/img/icons/icon-72x72.png",
          "sizes": "72x72",
          "type": "image/png"
        },
        {
          "src": myUrl + "/img/icons/icon-96x96.png",
          "sizes": "96x96",
          "type": "image/png"
        },
        {
          "src": myUrl + "/img/icons/icon-128x128.png",
          "sizes": "128x128",
          "type": "image/png"
        },
        {
          "src": myUrl + "/img/icons/icon-144x144.png",
          "sizes": "144x144",
          "type": "image/png"
        },
        {
          "src": myUrl + "/img/icons/icon-152x152.png",
          "sizes": "152x152",
          "type": "image/png"
        },
        {
          "src": myUrl + "/img/icons/icon-192x192.png",
          "sizes": "192x192",
          "type": "image/png"
        },
        {
          "src": myUrl + "/img/icons/icon-384x384.png",
          "sizes": "384x384",
          "type": "image/png"
        },
        {
          "src": myUrl + "/img/icons/icon-512x512.png",
          "sizes": "512x512",
          "type": "image/png"
        }
      ]
    }

    const stringManifest = JSON.stringify(manifest);
    const blob = new Blob([stringManifest], {type: 'application/json'});
    const manifestURL = URL.createObjectURL(blob);
    document.querySelector('#my-manifest').setAttribute('href', manifestURL);
}

注意点

最初にこの方法を試した時にはURLや画像が無効だというエラーが出続け、解消するのに苦労しました。

原因はURLの指定方法にありました。
通常はstart_urlやアイコンのURLは相対パスでよかったのですが、動的にmanifestを読み込ませる場合はフルパスを指定しないと有効になりませんでした。

参考資料

下記を参考にしました。
How to Setup Your Web App Manifest Dynamically Using Javascript

18
19
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
18
19