Web APIs that make web applications functionally closer to native ones

Clevertec. My team and I are currently developing a web version of banking using React. To give users access to features familiar to native applications and add new ones, we use the Web API. I’ll talk about them in detail in this article and reveal some subtleties.

Web Share API

The Web Share API allows web apps to share links, text, and files with other apps installed on the device, just like native apps do. For example, you can quickly share a payment receipt in the messenger without leaving the banking application.

The Web Share API has the following capabilities and limitations:

  • Only HTTPS sites can use the Web Share API. Additionally, to make development easier, the API runs on localhost.

  • Can only be triggered by certain actions, for example, a click. It cannot be fired on page load or via setTimeout().

  • You can use it to share URLs, text, or files.

  • The ability to share resources is available on both desktop and mobile devices.

To share links and text, use the promise-based share() method with a required properties object. To prevent the browser from throwing a TypeError, the object must contain at least one of the following properties: title, text, url, or files.

For example, you can share text without a URL or vice versa. Specifying all three options increases the flexibility of use cases. Let's say after executing the code below, the user has selected the email application as the target. The title parameter can become the subject of the message, text can become the body of the message, and files can become attachments.

if(navigator.share) {
  navigator.share({
    title: 'web.dev',
    text: 'Открой для себя web.dev',
    url: 'https://web.dev/'
  })
    .then(() => console.log('Удалось поделиться'))
    .catch((error) => console.log('Не удалось поделиться', error));
}

To share files, first check and call navigator.canShare(). Then include the files array in the navigator.share() call:

if(navigator.canShare && navigator.canShare({ files: filesArray })) {
  navigator.share({
    files: filesArray,
    title: 'web.dev',
    text: 'Открой для себя web.dev',
  })
    .then(() => console.log('Удалось поделиться'))
    .catch((error) => console.log('Не удалось поделиться', error));
} else {
  console.log('Ваша система не поддерживает обмен файлами');
}

Important: In this example, feature detection is implemented by checking navigator.canShare() rather than navigator.share(). The data object passed to canShare() only supports the files property. If navigator.canShare() returns true, then the ability to share filesArray is supported.

Support Web Share API on different devices, operating systems and browsers at the moment:

  • iOS: Safari, Chrome

  • Android: Chrome, Yandex, Edge

  • Windows: Chrome, Yandex, Edge, Opera

  • macOS: Safari

Not supported:

  • Android: Firefox, Samsung browser, Opera (files cannot be fumbled, only links and text)

  • Windows: Firefox

  • macOS: Chrome

Contact Picker API

The Contact Picker API provides an easy way for users to share contacts from their list. A button is added to the phone number entry field or next to it; when clicked, the device’s contact book opens, from which it is convenient to select the one you need.

To check if the contact selection API is supported, use:

const supported = ('contacts' in navigator && 'ContactsManager' in window)

The API is currently only supported on mobile devices. On Android it is Chrome, on IOS it is Safari. Before developing and testing the contact selection API, you must enable support for this feature on your device. On Android, it is now available in Chrome 80 or later by default.

But if you are on iOS, The Contact Picker API is considered an experimental feature and you should follow these instructions:

  1. Go to Settings, scroll down and select Safari

  2. Scroll down, click “Advanced”

  3. Select the “Experimental Features” menu and toggle Contact Picker API

The contacts object has getProperties() and select() methods. The getProperties() method returns the properties available on the user's device.

There is a specific list of properties that can be returned: names, phone numbers, email addresses, addresses and contact avatar:

const supported = ('contacts' in navigator && 'ContactsManager' in window)

interface ContactsManager {
  getProperties: () => Promise<ContactProperty[]>;
}

enum ContactProperty {
  "address" = "address",
  "email" = "email",
  "icon" = "icon",
  "name" = "name",
  "tel" = "tel",
}

async function checkPropertiesSupport(): Promise<void> {
  try {
    const supportedProperties = await navigator.contacts.getProperties();
    setContactProperties(supportedProperties);
  } catch {
    console.warn(
      "This browser doesn't support the Contact Picker API"
    );
  }
}

The list of supported properties will be returned as an array. For example in the above case we could get an array like [“email”, “name”, “tel”].

The select() method takes two arguments:

1. An array of contact properties, for example ( [“email”, “name”, “tel”] )

2. An object with a multiple parameter, which can be true or false. If set to true, multiple contacts can be selected at once.

interface ContactsManager {
  select: (
    properties: ContactProperty[],
    options?: ContactSelectOptions
  ) => Promise<ContactInfo[]>;
}

interface ContactInfo {
  address: Array<ContactAddress>;
  email: Array<string>;
  icon: Blob;
  name: Array<string>;
  tel: Array<string>;
};

async function selectContacts () {
  const contacts = await navigator.contacts.select(['name', 'tel'], { multiple: true });

  if (!contacts.length) {
    // нет выбранных контактов
    return;
  }

  return contacts;
}

selectContacts();

Security for using the contact selection API:

1. Access is carried out only at the browser level.

2. Works only over HTTPS protocol.

3. Cannot be activated by software. The user must allow selection from contacts, as if in a native application.

This is an additional layer of security to prevent unnecessary or malicious use of the API without user permission. These measures help ensure the security and privacy of user data when using this API.

Media Capture and Streams API

This API allows web applications to access media capture capabilities on a device. For example, you can activate the camera, read the barcode and redirect the user to a specific link.

Our application has an integrated system for accepting electronic payments, in which you can pay for anything by scanning a QR code. After clicking on “Scan QR” a window with a camera opens. Next, the camera detects a QR code and the user is redirected to the electronic payment tree.

For implementation we used the html5-qrcode library. Under the hood it uses the Media Capture and Streams API. Works on both desktop and mobile devices, supported by all major browsers. Quite lightweight – 56 Kb.

After import, we start the operation of the device’s camera using html5QrCode.start()

import { Html5Qrcode } from 'html5-qrcode';

const html5QrCode = new Html5Qrcode("reader");
html5QrCode.start(
  cameraId, 
  {
    fps: 10,
    qrbox: 250
  },
  qrCodeMessage => {
    // сделать что то когда код прочитан
  },
  errorMessage => {
    // если ошибка при чтении
  })
.catch(err => {
  // обработка ошибки
});

This method returns a promise initializing the QR code scanning.

After carrying out the necessary manipulations, we stop scanning the QR code using the html5QrCode.stop() method, which returns a promise to stop scanning.

html5QrCode.stop().then(ignore => {
  // остановлено сканирование QR-кода
}).catch(err => {
  // обработка ошибки
});

Summary

The main thing that Web APIs give us is the ability to provide a seamless transition from using a native application to the web version. If the mobile application is not available, there is a web version in which, thanks to technology, we ensure comfortable work and reduce the steps for performing routine actions as much as possible.

Somewhere they allow integration with native applications. For the user, this means that there is no need to understand new things and you can use familiar tools.

Future plans: WEB OTP API

In the end I decided to share my plans. We want to implement WEB OTP API on the project. This will allow you to automatically insert the code from SMS.

A message is sent to your phone to confirm payment. A modal window appears at the bottom of the screen confirming the insertion. And after clicking on “Allow”, the code will be inserted into the input field.

If you have successful experience using the Web OTP API and knowledge of the nuances, share it in the comments 🙂

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *