2

I'm trying to add to my webpage an option to share image and video using Web Share API. When testing it, I'm having the following problem: on Android + Chrome, it works sharing video and images, but when I execute the same code on iOS 14.4 Safari (running on iPhone 6s) I only get the text and URL sharing, not the files. Is someone having the same issue? Based on this it was supposed to work: https://caniuse.com/web-share

https://jsfiddle.net/ryb0x537/

Regards.

<div id="error"></div>
<form method="POST" action="/share/">
  <table>
    <tr>
      <td><label for="shared_title">Title:</label></td>
      <td><input id="shared_title" name="shared_title" value="Example Title"></td>
    </tr>
    <tr>
      <td><label for="shared_text">Text:</label></td>
      <td><input id="shared_text" name="shared_text" value="Example text"></td>
    </tr>
    <tr>
      <td><label for="shared_url">URL:</label></td>
      <td><input id="shared_url" name="shared_url" value="https://example.com/a?b=c"></td>
    </tr>
    <tr>
      <td><label for="shared_file">File(s):</label></td>
      <td><input id="shared_file" name="shared_file" type="file" multiple></td>
    </tr>
  </table>
  <input type="submit" value="Share">
</form>
<script>
document.querySelector('form').onsubmit = () => {
  const error = document.getElementById('error');
  const title = document.getElementById('shared_title').value;
  const text = document.getElementById('shared_text').value;
  const url = document.getElementById('shared_url').value;
  const files = document.getElementById('shared_file').files;

  let data = {};
  if (files.length > 0) {
    data.files = files;
  }
  if (title !== '')
    data.title = title;
  if (text !== '')
    data.text = text;
  if (url !== '')
    data.url = url;

  error.textContent = '';
  navigator.share(data)
    .then(() => {
  })
    .catch((err) => {
    console.log('Unsuccessful share');
    error.textContent = 'Share failed: ' + err.message;
  });

  return false;
};
</script>
Gabriel Schubert
  • 165
  • 4
  • 12

1 Answers1

2

It seems like Safari has trouble with file objects and chokes (throws a TypeError). I could get it to work by using blobs converted to files instead:

const blob = await fetch('https://cdn.glitch.com/f96f78ec-d35d-447b-acf4-86f2b3658491%2Fchuck.png?v=1618311092497').then(r=>r.blob())

const share = async (title, text, blob) => {
  const data = {
    files: [
      new File([blob], 'image.png', {
        type: blob.type,
      }),
    ],
    title: title,
    text: text,
  };
  try {
    if (!(navigator.canShare(data))) {
      throw new Error('Can\'t share data.', data);
    };
    await navigator.share(data);
  } catch (err) {
    console.error(err.name, err.message);
  }
};
DenverCoder9
  • 2,024
  • 11
  • 32
  • I tried your solution but it stills only working on Android for file sharing. I'm running on local server using adhoc ssl context. Here is the code: https://jsfiddle.net/5gtoLw7b/3/ – Gabriel Schubert Apr 20 '21 at 18:29
  • Sorry. I tried others apps and: on IOS/Safari the image now appears to be shared on apps like Message and Gmail within the text. On Whatsapp only the variable text is sent. Is it expected? I'm running on local server using adhoc ssl context. Here is the code: https://jsfiddle.net/5gtoLw7b/3/ – Gabriel Schubert Apr 20 '21 at 18:37
  • For sharing on Whatsapp: sending no text (only image) works on Safari. If I try to send both, it only sends the text content – Gabriel Schubert Apr 20 '21 at 18:44
  • 1
    Your code is absolutely correct. It's WhatsApp's share implementation that's weird. I got it to work by only sharing an image (without any accompanying text): ```js const data = { files: [ new File([blob], 'image.png', { type: blob.type, }), ], }; try { if (!(navigator.canShare(data))) { throw new Error('Can\'t share data.', data); }; await navigator.share(data); } catch (err) { console.error(err.name, err.message); } ``` Other apps like Messages or Gmail handle the initial code correctly, it's just WhatsApp that's off. – DenverCoder9 Apr 22 '21 at 07:46
  • Yes as @DenverCoder9 mentioned without any accompanying text able to send image but isn't there any work around to send image with text? – kushal Baldev Jul 19 '23 at 08:23