블로그 목록

VisionCamera로 QR·바코드 스캐너 만들기 — expo-barcode-scanner가 사라진 뒤

앱에 QR 스캔 기능을 붙여야 했다. 예전 프로젝트에서는 expo-barcode-scanner를 그냥 갖다 썼는데, 이번에 다시 보니 deprecated 상태였다. Expo 공식 문서도 이제 expo-cameraCameraViewreact-native-vision-camera를 쓰라고 안내한다.

expo-camera로도 되긴 하는데, 스캔 성능이나 프레임 처리 세밀함을 생각하면 VisionCamera 쪽이 확실히 낫다. 예전엔 VisionCamera로 바코드를 읽으려면 프레임 프로세서 + MLKit 플러그인을 직접 붙여야 해서 세팅이 꽤 번거로웠는데, v3부터 codeScanner가 내장돼서 훨씬 간단해졌다.

설치

npx expo install react-native-vision-camera

Expo 프로젝트라면 config plugin으로 카메라 권한 문구를 넣어준다. app.json에 이렇게.

{
  "plugins": [
    [
      "react-native-vision-camera",
      { "cameraPermissionText": "QR 스캔을 위해 카메라 접근이 필요합니다." }
    ]
  ]
}

네이티브 모듈이라 Expo Go에서는 안 돌아간다. npx expo run:ios 같은 dev client 빌드가 필요하다. 이거 모르고 Expo Go에서 계속 크래시나서 한참 헤맸다.

권한 요청

카메라를 켜기 전에 권한부터 받아야 한다. VisionCamera는 훅으로 이걸 깔끔하게 처리해준다.

import { useCameraPermission, useCameraDevice } from 'react-native-vision-camera';

const { hasPermission, requestPermission } = useCameraPermission();

useEffect(() => {
  if (!hasPermission) requestPermission();
}, [hasPermission]);

스캐너 붙이기

핵심은 useCodeScanner 훅이다. 읽을 코드 타입을 배열로 지정하고, 인식됐을 때 콜백만 넘기면 끝이다.

import { Camera, useCodeScanner } from 'react-native-vision-camera';

function Scanner() {
  const device = useCameraDevice('back');

  const codeScanner = useCodeScanner({
    codeTypes: ['qr', 'ean-13', 'code-128'],
    onCodeScanned: (codes) => {
      const value = codes[0]?.value;
      if (value) console.log('스캔됨:', value);
    },
  });

  if (!device) return null;

  return (
    <Camera
      style={StyleSheet.absoluteFill}
      device={device}
      isActive={true}
      codeScanner={codeScanner}
    />
  );
}

codeTypes'qr'만 넣으면 QR 전용, EAN·Code128을 같이 넣으면 상품 바코드까지 읽는다.

중복 스캔을 막아야 한다

여기서 실전 팁 하나. onCodeScanned은 카메라가 코드를 잡고 있는 동안 계속, 초당 수십 번씩 불린다. 스캔 한 번에 화면을 넘기려 하면 콜백이 폭주해서 네비게이션이 여러 번 쌓인다.

ref 플래그로 한 번만 처리하도록 잠가주는 게 편하다.

const locked = useRef(false);

onCodeScanned: (codes) => {
  if (locked.current) return;
  locked.current = true;
  const value = codes[0]?.value;
  router.push({ pathname: '/result', params: { value } });
},

isActive={false}로 카메라를 잠깐 꺼주는 방법도 있는데, 다시 스캔 화면으로 돌아올 때 플래그만 풀어주면 되니까 나는 위 방식이 더 깔끔했다.


정리하면 VisionCamera v3의 codeScanner는 별도 플러그인 없이 QR·바코드를 다 처리한다. 주의할 점은 Expo Go가 아니라 dev client로 돌려야 한다는 것, 그리고 콜백 폭주를 막을 잠금 처리 정도다. 세팅만 넘기면 실제 스캔 코드는 20줄이 안 된다.