PromleeBlog
sitemapaboutMe

posting thumbnail
Expo에서 권한 요청 처리하기
Handling Permissions in Expo

📅

🚀

들어가기 전에 🔗

Expo로 모바일 앱을 개발할 때, 사용자의
개인 정보나 기기 기능
을 다루기 위해서는 권한(permission)을 먼저 요청해야 합니다. 예를 들어, 카메라를 사용하려면 카메라 권한을 요청해야 하고, 사용자의 위치를 얻기 위해선 위치 권한이 필요합니다.
Expo에서는 이러한 권한 요청을 쉽게 도와주는 도구들을 제공하고 있습니다. 오늘은 공식 문서(Expo Permissions 가이드)를 바탕으로, Expo에서 권한을 처리하는 방법을 하나하나 살펴보겠습니다.

🚀

Expo에서 권한 요청하는 기본 구조 🔗

Expo는 expo-modulesexpo-permissions 패키지를 통해 다양한 권한 요청 기능을 제공합니다. 보통 다음과 같은 순서로 권한을 처리합니다:
  1. 권한 상태 확인
  2. 권한 요청
  3. 결과에 따라 기능 수행
가장 기본적인 구조는 다음과 같습니다.
import * as Location from 'expo-location';
 
const getLocation = async () => {
  const { status } = await Location.requestForegroundPermissionsAsync();
    if (status !== 'granted') {
    alert('위치 권한이 필요합니다.');
    return;
  }
    const location = await Location.getCurrentPositionAsync({});
  console.log(location);
};
이 코드는 사용자에게 위치 권한을 요청하고, 권한이 승인되었을 경우에만 위치 정보를 받아옵니다.

🚀

다양한 권한 예시들 🔗

Expo에서는 여러 가지 권한을 다룰 수 있습니다. 여기서는 대표적인 권한 몇 가지를 예시와 함께 살펴보겠습니다.
🖐️
dev 모드가 필수적이며 각 패키지 설치 후 명령어로 네이티브 코드와 동기화를 해야 합니다.
npx expo prebuild --platform ios
npx expo run:ios
 
npx expo prebuild --platform android
npx expo run:android

1. 카메라 권한 🔗

참고: expo-camera 공식 문서
다음 명령어로 카메라 권한 패키지를 설치합니다.
npx expo install expo-camera
app.json에 다음과 같이 추가합니다.
{
  "expo": {
    "plugins": [
      [
        "expo-camera",
        {
          "cameraPermission": "Allow $(PRODUCT_NAME) to access your camera", // 카메라 권한 요청 메시지
          "microphonePermission": "Allow $(PRODUCT_NAME) to access your microphone", // 마이크 권한 요청 메시지
          "recordAudioAndroid": true // 마이크 권한 요청 여부
        }
      ]
    ]
  }
}
카메라 권한을 요청하는 코드는 다음과 같습니다.
import * as Camera from 'expo-camera';
const requestCameraPermission = async () => {
  const { status } = await Camera.requestCameraPermissionsAsync();
    if (status !== 'granted') {
    alert('카메라 접근 권한이 필요합니다.');
    return;
  }
    console.log('카메라 권한이 승인되었습니다.');
};

2. 미디어 라이브러리 (사진 접근) 권한 🔗

참고: expo-media-library 공식 문서
다음 명령어로 미디어 라이브러리 패키지를 설치합니다. 또한 미디어 라이브러리 패키지는 카메라 권한 패키지와 함께 설치됩니다.
npx expo install expo-media-library
app.json에 다음과 같이 추가합니다.
{
  "expo": {
    "plugins": [
      [
        "expo-media-library",
        {
          "photosPermission": "Allow $(PRODUCT_NAME) to access your photos.",
          "savePhotosPermission": "Allow $(PRODUCT_NAME) to save photos.",
          "isAccessMediaLocationEnabled": true
        }
      ]
    ]
  }
}
미디어 라이브러리 권한을 요청하는 코드는 다음과 같습니다.
import * as MediaLibrary from 'expo-media-library';
const requestMediaLibraryPermission = async () => {
  const { status } = await MediaLibrary.requestPermissionsAsync();
    if (status !== 'granted') {
    alert('사진 접근 권한이 필요합니다.');
    return;
  }
    console.log('사진 권한 승인 완료');
};

3. 알림 권한 🔗

참고: expo-notifications 공식 문서
다음 명령어로 알림 패키지를 설치합니다.
npx expo install expo-notifications
알림 권한을 요청하는 코드는 다음과 같습니다.
import * as Notifications from 'expo-notifications';
const requestNotificationPermission = async () => {
  const { status } = await Notifications.requestPermissionsAsync();
    if (status !== 'granted') {
    alert('알림 권한이 필요합니다.');
    return;
  }
    console.log('알림 권한 승인됨');
};

4. 마이크 권한 🔗

참고: expo-av 공식 문서
다음 명령어로 마이크 패키지를 설치합니다.
npx expo install expo-av
app.json에 다음과 같이 추가합니다.
{
  "expo": {
    "plugins": [
      [
        "expo-av",
        {
          "microphonePermission": "Allow $(PRODUCT_NAME) to access your microphone."
        }
      ]
    ]
  }
}
마이크 권한을 요청하는 코드는 다음과 같습니다.
import * as Audio from 'expo-av';
const requestMicrophonePermission = async () => {
  const { status } = await Audio.requestPermissionsAsync();
    if (status !== 'granted') {
    alert('마이크 권한이 필요합니다.');
    return;
  }
    console.log('마이크 권한이 승인되었습니다.');
};

5. 위치 권한 🔗

참고: expo-location 공식 문서
다음 명령어로 위치 패키지를 설치합니다.
npx expo install expo-location
app.json에 다음과 같이 추가합니다.
{
  "expo": {
    "plugins": [
      [
        "expo-location",
        {
          "locationAlwaysAndWhenInUsePermission": "Allow $(PRODUCT_NAME) to use your location."
        }
      ]
    ]
  }
}
위치 권한을 요청하는 코드는 다음과 같습니다.
import * as Location from 'expo-location';
const requestLocationPermission = async () => {
  const { status } = await Location.requestForegroundPermissionsAsync();
    if (status !== 'granted') {
    alert('위치 권한이 필요합니다.');
    return;
  }
    console.log('위치 권한이 승인되었습니다.');
};

🚀

권한 상태 확인과 구분 🔗

권한 상태는 일반적으로 다음 중 하나입니다:
const checkCameraPermission = async () => {
  const { status } = await Camera.getCameraPermissionsAsync();
    if (status === 'granted') {
    console.log('이미 권한이 승인됨');
  } else {
    console.log('권한이 아직 없거나 거부됨');
  }
};
이렇게 상태를 미리 확인하면, 사용자에게 불필요한 권한 요청을 줄일 수 있습니다.

🚀

권한 요청 시 주의할 점 🔗

사용자에게 설명하는 메시지 중요성 🔗

권한을 요청할 때, 사용자가 거부하지 않도록 설득력 있는 메시지를 함께 보여주는 것이 좋습니다. 단순히 “권한이 필요합니다”보다는, 기능과 연결하여 “사진 업로드를 위해 사진 접근 권한이 필요합니다”와 같이 설명하는 것이 더 효과적입니다.
이는 추후 스토어 심사 시 자주 반려되는 사항입니다.

🚀

결론 🔗

Expo에서 권한을 처리하는 방식은 매우 직관적이지만, 플랫폼별 세부 설정(iOS, Android)과 사용자 경험까지 고려하면 꽤 신중하게 접근해야 합니다.
권한 요청은 단순한 기술적인 처리 그 이상으로, 사용자의 신뢰와 직결되는 요소입니다. 따라서 각 권한의 목적을 명확히 하고, 필요한 경우에만 정중하게 요청하는 습관을 들이는 것이 좋습니다.
앞서 살펴본 예시들을 바탕으로, 프로젝트에 맞는 권한 요청 흐름을 구성해보시길 권장드립니다.

참고 🔗