みかづきブログ・カスタム

基本的にはちょちょいのほいです。

Web Share API を使って複数のファイルをシェアする際、順序が保証されない 📱

以前、iOS15でWeb Share APIを試しました

blog.kimizuka.org

その際は気づかなかったのですが、ファイルを複数シェアしようとすると順番が保証されないということに気づきました。


DEMO

https://develop.kimizuka.org/web-share-api-multiple-files/

Web Share APIを使って3枚の画像をシェアしようとしているのですが、シェア方法を選択するたびに画像の順番が入れ替わっています。


ソースコード

<canvas></canvas>
<canvas></canvas>
<canvas></canvas>
<button>share</button>
<script>
  [].slice.call(document.querySelectorAll('canvas')).forEach((canvas, i) => {
    const ctx = canvas.getContext('2d');

    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = 'white';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.font = '40px serif';
    ctx.fillText(i, canvas.width / 2, canvas.height / 2)
  });

  document.querySelector('button').addEventListener('click', async () => {
    const param = { files: [] };
    const canvasList = document.querySelectorAll('canvas');

    for (let i = 0; i < canvasList.length; ++i) {
      param.files.push(canvasToPngFile(document.querySelectorAll('canvas')[i], i)); // 0, 1, 2の順で配列に収納
    }

    await navigator.share(param).done(() => {
      console.log('share');
    }).catch((err) => {
      console.error(err);
    });
  });

  function canvasToPngFile(canvas, name) {
    const type = 'image/png';
    const dataUrl = canvasToBase64(canvas, type);
    const decodedData = window.atob(dataUrl.replace(/^.*,/, ''));
    const buffers = new Uint8Array(decodedData.length);

    for (let i = 0; i < decodedData.length; ++i) {
      buffers[i] = decodedData.charCodeAt(i);
    }

    try {
      const blob = new Blob([buffers.buffer], {
        type
      });

      return new File([ blob ], `${ name }.png`, { type });

    } catch {
      return null;
    }
  }

  function canvasToBase64(canvas, type = 'image/png') {
    return canvas.toDataURL(type);
  }
</script>




navigator.shareに渡している配列を確認したところ、想定通りの順序になっていることを確認できたので、OS側で受け取ったファイルを順不同で処理しているのだと思われます。
あんまり困ることはなさそうではあるのですが、例えば、4コマ漫画を4つの画像でシェアするボタンをつくろうとしたときなどに困ることになります。

現状、対策のしようもないので、Web Share APIの動向を注意深く見守っていこうと思います。