- react-native 버전이 0.72 버전 이상인 경우에는 아래와 같이 Podfile 내에 추가를 해줍니다.
######### 기존에 있는 해당 내용을 삭제합니다.
# Resolve react_native_pods.rb with node to allow for hoisting
# require Pod::Executable.execute_command('node', ['-p',
# 'require.resolve(
# "react-native/scripts/react_native_pods.rb",
# {paths: [process.argv[1]]},
# )', __dir__]).strip
######## 해당 내용을 추가합니다.
def node_require(script)
# Resolve script with node to allow for hoisting
require Pod::Executable.execute_command('node', ['-p',
"require.resolve(
'#{script}',
{paths: [process.argv[1]]},
)", __dir__]).strip
end
######## 해당 내용을 추가합니다.
node_require('react-native/scripts/react_native_pods.rb')
node_require('react-native-permissions/scripts/setup.rb')
platform :ios, '13.0'
prepare_react_native_project!
######## 해당 내용을 추가합니다 : 사용할 권한을 추가합니다.
setup_permissions([
'Camera',
]);
# with react-native < 0.72
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
####### 해당 부분을 추가합니다.
require_relative '../node_modules/react-native-permissions/scripts/setup'
platform :ios, '13.0'
prepare_react_native_project!
######## 해당 내용을 추가합니다 : 사용할 권한을 추가합니다.
setup_permissions([
'Camera',
]);
3. [터미널] Podfile을 갱신합니다.
💡 Podfile을 갱신합니다.
- 위에서 변경한 Podfile에 대해서 이를 업데이트를 시켜줍니다.
$ npx pod-install
# or
$ cd ios && pod install
4. [info.plist] 추가 권한을 추가합니다
💡 추가 권한을 추가합니다
- 이전에는 Podfile에서 필요로 하는 권한만 추가하였습니다. 이와 관련되어 다른 내용이 궁금하시면 아래의 링크를 참고하시면 도움이 됩니다.
💡 react-native-permissions의 request() 함수를 이용하여서 지정된 권한을 요청하는 함수를 호출하여 결과값(Permission State)이 GRANTED가 되었을 경우 사용자가 권한에 대한 허용을 하였습니다.
import { Alert, Platform } from "react-native";
import { PERMISSIONS, RESULTS, request } from "react-native-permissions";
/**
* '앱의 권한'을 공통으로 관리하는 유틸입니다.
*/
class PermissionUtil {
/**
* [필수] 모든 권한에 대해서 기본적으로 디바이스 플랫폼을 체크합니다.
* @returns {boolean} true : 사용 가능 디바이스 플랫폼, false : 사용 불가능 디바이스 플랫폼
*/
cmmDevicePlatformCheck = (): boolean => {
let isUseDevice = true;
if (Platform.OS !== "ios" && Platform.OS !== "android") !isUseDevice;
return isUseDevice;
}
/**
* 카메라 권한
* @return
*/
cmmReqCameraPermission = async (): Promise<void> => {
// 모든 권한에 대해 디바이스 플랫폼을 체크합니다. (해당 되지 않는 경우 종료합니다.)
if (!this.cmmDevicePlatformCheck()) return;
const platformPermissions = Platform.OS === "ios" ? PERMISSIONS.IOS.CAMERA : PERMISSIONS.ANDROID.CAMERA;
try {
// Request Permission
const result = await request(platformPermissions);
if (result == RESULTS.GRANTED) {
console.log("권한이 허용되었습니다.")
}
} catch (err) {
Alert.alert("Camera permission err");
console.warn(err);
}
}
}
export default PermissionUtil();
2. 결과 확인
3. 다중 권한 요청
1. 함수 선언부
💡 해당 기능에서는 PermissionUtil로 구성을 하였습니다.
1. cmmAccessDevicePlatformCheck()는 앱 권한을 가지는 디바이스 플랫폼인지 여부를 체크를 하는 함수입니다.
2. cmmPermsArrCheck()는 권한 체크에서 모두 다 ‘허용’ 했는지 여부를 체크하는 함수입니다.
3. cmmReqPermis()는 실제로 권한 요청을 위해 데이터를 파라미로 전달받으면 1,2번이 수행되고 권한 요청을 수행합니다.
import { APP_PERMISSION_CODE } from "common/codes/CommonCode";
import { Alert, Linking, Platform } from "react-native";
import { PERMISSIONS, RESULTS, request, requestMultiple, Permission, check } from "react-native-permissions";
/**
* '앱의 권한'을 공통으로 관리하는 유틸입니다.
*/
class PermissionUtil {
/**
* 접근 가능한 디바이스 플랫폼을 체크합니다.
*
* @returns {boolean} true : 사용 가능 디바이스 플랫폼, false : 사용 불가능 디바이스 플랫폼
*/
private cmmAccessDevicePlatformCheck = (): boolean => {
let isUseDevice = true;
if (Platform.OS !== "ios" && Platform.OS !== "android") !isUseDevice;
return isUseDevice;
}
/**
* 권한 체크에서 모두 '허용(granted)'을 하였는지 여부를 체크합니다.
*
* @param {Permission[} permsCodeArr
* @returns {Promise<Permission[]>} 권한 중 '허용'을 모두 한 경우 빈 배열이며 '허용'을 하지 않으면 배열로 반환합니다.
*/
private cmmPermsArrCheck = async (permsCodeArr: Permission[]): Promise<Permission[]> => {
let notGrantedArr: Permission[] = [];
// [STEP1] 전달 받은 배열을 순회하면서 권한을 허용했는지 체크합니다.
for (let permsItem of permsCodeArr) {
// [STEP2] 동일한 플랫폼(andriod, ios)의 코드가 아니면 undefined가 발생합니다. 이를 제외하고 수행합니다.
if (permsItem != undefined) {
//[STEP3] react-native-permissions 함수를 이용해 권한을 체크합니다.
let permsCheck = await check(permsItem);
switch (permsCheck) {
// [CASE1] 권한 상태가 수락(granted) 상태인 경우
case "granted":
break;
// [CASE2] 권한 상태가 수락되지 않은 상태 : 배열을 저장합니다.
case "blocked":
case "denied":
case "limited":
case "unavailable":
notGrantedArr.push(permsItem);
break;
}
}
}
return notGrantedArr;
}
/**
* 권한 체크를 수행할 것을 배열로 전달받습니다.
*
* @param {Permission[]} permsArr
* @returns
*/
cmmReqPermis = async (permsArr: Permission[]): Promise<void> => {
console.log("[+] 함수 실행완료")
// [CASE1] 모든 권한에 대해 디바이스 플랫폼을 체크합니다. (해당 되지 않는 경우 종료합니다.)
if (!this.cmmAccessDevicePlatformCheck()) return;
// [CASE2] 허용되지 않은 권한을 확인합니다.
const notGrantedArr = await this.cmmPermsArrCheck(permsArr);
const notGrantedArrLen = notGrantedArr.length;
/**
* [CASE3] 허용되지 않은 권한이 있는지 체크하여 분기 처리를 합니다.
* - 허용되지 않은 권한이 없을 경우 - 종료
* - 허용되지 않은 권한이 있는 경우 - 권한요청
*/
if (notGrantedArrLen == 0) return;
else {
await requestMultiple(notGrantedArr)
.then((statues) => {
let permsCnt = 0; // 허용되지 않은 권한의 종류
notGrantedArr.map((permsItem) => statues[permsItem] === RESULTS.GRANTED ? permsCnt += 1 : 0);
if (notGrantedArrLen === permsCnt) return;
else {
Linking.openSettings(); // 핸드폰 상 설정 페이지
Alert.alert("권한을 모두 허용해주세요");
}
})
.catch((e) => {
console.log("[-] 권한 요청에서 에러가 발생하였습니다.", e)
})
}
}
}
export default new PermissionUtil();
2. 코드 선언부
💡 APP_PERMISSION_CODE이라는 코드를 구성하여서 각각 안드로이드, iOS 별로 앱 권한을 요청할 수 있도록 구성하였습니다.
/**
* Andriod, IOS 앱 권한 코드
* - calendar : 캘린더 접근 권한
* - camera : 카메라 접근 권한
* - microphone: 마이크 접근 권한
* - mediaLibaray : 외부 저장소 접근 권한
*/
export const APP_PERMISSION_CODE = {
"calendar": [PERMISSIONS.ANDROID.READ_CALENDAR, PERMISSIONS.ANDROID.WRITE_CALENDAR, PERMISSIONS.IOS.CALENDARS],
"camera": [PERMISSIONS.ANDROID.CAMERA, PERMISSIONS.IOS.CAMERA],
"microphone": [PERMISSIONS.ANDROID.RECORD_AUDIO, PERMISSIONS.IOS.MICROPHONE],
"mediaLibaray": [PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE, PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE, PERMISSIONS.IOS.MEDIA_LIBRARY],
}