diff --git a/docs/recipes/ReactNativeVisionCamera.md b/docs/recipes/ReactNativeVisionCamera.md new file mode 100644 index 00000000..d7a429dd --- /dev/null +++ b/docs/recipes/ReactNativeVisionCamera.md @@ -0,0 +1,418 @@ +--- +title: React Native Vision Camera +description: How to integrate VisionCamera in Ignite v9+ +tags: + - Expo + - VisionCamera + - react-native-vision-camera +last_update: + author: Frank Calise +publish_date: 2023-10-23 +--- + +# VisionCamera + +## Overview + +VisionCamera is a powerful, high-performance React Native Camera library. It's both feature-rich and flexible! The library provides the necessary hooks and functions to easily integrate camera functionality in your app. + +In this example, we'll take a look at wiring up a barcode scanner. This tutorial is written for the Ignite v9 Prebuild workflow, however it generally still applies to DIY or even a bare react-native project. + +## Installation + +If you haven't already, spin up a new Ignite application: + +```terminal +npx ignite-cli@latest new PizzaApp --remove-demo --workflow=prebuild --yes +cd PizzaApp +``` + +Next, let's install the necessary dependencies. You can see complete installation instructions for `react-native-vision-camera` [here](https://react-native-vision-camera.com/docs/guides). + +```terminal +npx expo install react-native-vision-camera +``` + +Add the plugin to `app.json` as per the documentation. It'll look like the following if you have the default Ignite template: + +```json +"plugins": [ + "expo-localization", + [ + "expo-build-properties", + { + "ios": { + "newArchEnabled": false + }, + "android": { + "newArchEnabled": false + } + } + ], + [ + "react-native-vision-camera", + { + "cameraPermissionText": "$(PRODUCT_NAME) needs access to your Camera.", + "enableCodeScanner": true + } + ] +], +``` + +> **Note:** `$(PRODUCT_NAME)` comes from the iOS project build configuration, this will be populated with the app name at runtime as long as it's configured properly (in this case, it is in the Ignite boilerplate) + +To get this native dependency working in our project, we'll need to run prebuild so Expo can execute the proper native code changes for us. Then we can boot up the app on a device. + +```terminal +npx expo prebuild +yarn android +``` + +Since the simulators do not offer a good way of testing the camera for this recipe, we'll be creating an Android build to test on an actual device. This is for convenience, as it's a bit easier to achieve than running on an iOS device, however both would work. + +## Permissions + +Before we can get to using the camera on the device, we must get permission from the user to do so. Let's edit the Welcome screen in Ignite to reflect the current permission status and a way to prompt the user. + +```tsx +import { observer } from "mobx-react-lite"; +import React, { FC } from "react"; +import { AppStackScreenProps } from "../navigators"; +import { Camera, CameraPermissionStatus } from "react-native-vision-camera"; +import { Linking, View, ViewStyle } from "react-native"; +import { Button, Screen, Text } from "app/components"; + +interface WelcomeScreenProps extends AppStackScreenProps<"Welcome"> {} + +export const WelcomeScreen: FC = observer( + function WelcomeScreen(_props) { + const [cameraPermission, setCameraPermission] = + React.useState(); + + React.useEffect(() => { + Camera.getCameraPermissionStatus().then(setCameraPermission); + }, []); + + const promptForCameraPermissions = React.useCallback(async () => { + const permission = await Camera.requestCameraPermission(); + Camera.getCameraPermissionStatus().then(setCameraPermission); + + if (permission === "denied") await Linking.openSettings(); + }, [cameraPermission]); + + if (cameraPermission == null) { + // still loading + return null; + } + + return ( + + + + Camera Permission:{" "} + {cameraPermission === null ? "Loading..." : cameraPermission} + + {cameraPermission !== "granted" && ( +