Простой QR сканнер своими руками без мам, пап и кредитов на React Native

Ниже небольшой гаед, как сделать простенькое приложение на react-native

Ставим задачу. Что должна делать аппка?

  1. Сканировать qr код с текстом.
  2. Собирать url в формате mydomain.com?code={отсканированный код}
  3. Открывать собранный url в браузере по умолчанию в системе.

Есть ли существующие аналоги?

IOS

На яблочных смартфонах: это можно реализовать вообще без кода. Через стандартное приложение shortcuts. Там это можно сделать в несколько блоков-действий:

../../../../Assets/QR сканнер/photo_2024-03-05_23-49-50.jpg

Android

С этим сложнее: на этой операционке нет такого прекрасного механизма. Но можно воспользоваться готовыми приложениями по сканированию qr кодов, которые в настройках позволяют указать кастомные url для "действий" после сканирования QR.

Из тех, что нашел:

Но они систематически проигрывают рекламу, а за нормальную версию придётся заплатить.

Чем не устраивают существующие решения?

На яблоке -- более чем устраивает. На андроиде приходится запускать около-мусорные приложения. Хотелось бы единого подхода для всех платформ.

На чём пишем?

Чтобы не изобретать велосипеды, пишем на react-native с компонентами от expo. У них как раз есть уже написанный сканнер qr кодов.

Разворачиваем окружение

Идём сюда, и видим, что для создания проекта нам нужна node.js на компьютере.
А после установки, нужно лишь выполнить команду

npx create-expo-app MyProjectName

Что дальше?

Идём сюда и видим, что у нас есть существующий компонент от expo, который умеет работать с камерой и qr кодами. И при скане QR он дёргает заданный нами callback.

Делаем!

Устанавливаем нужные зависимости

npx expo install expo-camera

В app.json дописываем тексты для запроса пермишнов:

{
  "expo": {
    "plugins": [
      [
        "expo-camera",
        {
          "cameraPermission": "Allow $(PRODUCT_NAME) to access your camera",
        }
      ]
    ]
  }
}

Этот параметр будет выпрашивать у айфоноюзера выдать разрешения на использование камеры приложением.

Делаем! (1)

import { CameraView, useCameraPermissions } from 'expo-camera/next';

export default fucntion App(){
	...
	const [permission, requestPermission] = useCameraPermissions();
	const [qrContent, setQrContent] = useState(null);
	...
	requestPermission();

	if (!permission){
		... // обработка ситуации, когда пользователь -- жадиниа
	}

	const gotoLink = () => Linking.openURL(qrContent);
	const onBarcodeScanned = scanResult => setQrContent('http://mydomain.com/code/' + scanResult.data); 

	return (
    <View style={styles.container}>
      <CameraView style={styles.cameraView}
        barCodeScannerSettings={{ barCodeTypes: ["qr"], }}
        onBarcodeScanned={onBarcodeScanned}>
      </CameraView>
      <Button style={styles.btn} title={qrContent} onPress={gotoLink} />
    </View>
	 );
}

Сначала дёргаем хук, запрашивающий полномочия на камеру, если они ещё не были предоставлены пользователем.

Затем делаем пару простейших функций-хендлеров:

  1. gotoLink -- будет отрабатывать по нажатию на кнопку на экране, и редиректить пользователя на нужный нам URL
  2. onBarcodeScanned(scanResult) -- будет вызываться, когда произойдет успешное сканирвоание qr кода нашим встроенным модулем next/camera

Делаем разметку нашей вьюхи:

Внутри гланой вью у нас почти-ничего не будет. Лишь CameraView, которая будет отвечать за отображение картинки с камеры и сканирование QR кодов, и Button, по нажатию на которую пользователя будет перебрасывать на нужный нам сайт.

Собсна всё. Базовый скелет приложения готов. Осталось причесать, сделать разные красивости и экран с настройками, где можно было бы настраивать нужный нам домен.

По поводу сборки итогового билда приложения и выкладывания его в маркеты -- будет отдельный пост.