티스토리 뷰
[React-native] IOS, android에서 디바이스 설정 창 (app setting) 열기 및 app 밖의 상태 감지하기
AlgoRoot 2022. 10. 10. 20:58
안녕하세요. 오늘은 리엑트 네이티브에서 앱 디바이스 설정 창을 여는 방법에 대해 소개하겠습니다.
해당 기능은 유저가 어플리케이션의 알림 상태를 동의하지 않았을 경우 해당 애플리케이션 설정 창에서 알림을 허용하는 액션이 필요할 때와 같은 경우에 사용할 수 있습니다.
설정 후 다시 앱에 돌아왔을 때 동의 유무에 따른 분기처리 방법도 같이 말씀드리고자 합니다.
앱 설정 창 열기
앱 설정을 여는 것은 기본적으로 Linking에서 openSetting이라는 메서드를 제공합니다.
import { Linking } from 'react-native';
Linking.openSettings();
저 같은 경우는 유저가 알림설정을 했는지 안 했는지에 따라서 스크린 분기 처리가 필요했는데요.
설정을 한 후 다시 앱에 돌아갔을 때 유저가 알림설정을 허용했기 때문에 다른 스크린을 보여줘야 하지만 렌더링이 발생하지 않아 앱 알림을 허용하기 전에 보여줘야 할 스크린과 같게 됩니다.
그래서 앱 밖에서 앱 내로 들어왔다는 상태값을 감지할 필요가 있는데요. 이는 React-native에서 제공하는 AppState를 사용하면 됩니다.
AppState : AppStateStatic
AppState는 AppStateStatic이라는 인터페이스를 가집니다. 가지고 있는 properties와 method를 응용하여 app 상태를 감지할 수 있습니다.
export type AppStateEvent = 'change' | 'memoryWarning' | 'blur' | 'focus';
export type AppStateStatus = 'active' | 'background' | 'inactive' | 'unknown' | 'extension';
export interface AppStateStatic {
currentState: AppStateStatus;
isAvailable: boolean;
addEventListener(type: AppStateEvent, listener: (state: AppStateStatus) => void): NativeEventSubscription;
removeEventListener(type: AppStateEvent, listener: (state: AppStateStatus) => void): void;
}
아래와 같은 코드를 통해 현재 App 상태를 상태 값으로 관리할 수 있게 됩니다. appStateVisible==='active'인 상태가 app에 접속한 상태가 됩니다.
import React, { useRef, useState, useEffect } from "react";
import { AppState } from "react-native";
const Example = () => {
const appState = useRef(AppState.currentState);
const [appStateVisible, setAppStateVisible] = useState(appState.current);
React.useEffect(() => {
// appState 변화 구독
const subscription = AppState.addEventListener('change', (nextAppState) => {\
// 앱 현재 상태에 감지된 state 넣기
appState.current = nextAppState;
// 상태값에 현재 상태 넣기
setAppStateVisible(appState.current);
});
// 구독 해지
return () => {
subscription.remove();
};
}, []);
return (
..
)
}
export default Example;
저는 유저가 앱 알림설정을 했는지 안 했는지에 대한 유무 사이드 이펙트에서 가져왔는데요. authStatus === ture 라면 유저가 앱 알림 설정을 허용한 상태입니다.
의존성 배열에 appState와 유저의 알림설정 허용 유무에 대한 상태를 넣고 appState가 active인 상태가 아니라면 리턴 시켜 active인 경우에만 해당 값을 setState 해줍니다.
React.useEffect(() => {
if (appStateVisible !== 'active') return;
async function checkPermissionStatus() {
const authStatus = await getHasPermission();
setIsAuthorizedNotifications(!!authStatus);
}
checkPermissionStatus();
}, [getHasPermission, appStateVisible]);
결론적으로 유저가 background에있는지 app안에 있는지 감지가 되어 앱 설정에서 알림을 허용하거나 해제하고 바로 앱으로 돌아왔을 시에 해당 스크린이 리랜더링 되면서 분기 처리에 맞는 스크린이 보여지게 됩니다.
const ExampleScreen = () => {
const [isAuthorizedNotifications, setIsAuthorizedNotifications] =
React.useState<boolean | null>(null);
.
.
.
return (
<CommonLayout h={'100%'} px={'16px'} bgColor={'#FFFFFF'}>
{isAuthorizedNotifications ? (
<AuthorizedNotiScreen />
) : (
<UnAuthorizedNotiScreen />
)}
</CommonLayout>
);
}
export default ExampleScreen;
전체 코드
import React from 'react';
import { AppState } from 'react-native';
const ExampleScreen = () => {
const appState = React.useRef(AppState.currentState);
const [appStateVisible, setAppStateVisible] = React.useState(
appState.current,
);
const { getHasPermission } = useFCMPermissionService();
const [isAuthorizedNotifications, setIsAuthorizedNotifications] =
React.useState<boolean | null>(null);
React.useEffect(() => {
const subscription = AppState.addEventListener('change', (nextAppState) => {
appState.current = nextAppState;
setAppStateVisible(appState.current);
});
return () => {
subscription.remove();
};
}, []);
React.useEffect(() => {
if (appStateVisible !== 'active') return;
async function checkPermissionStatus() {
const authStatus = await getHasPermission();
setIsAuthorizedNotifications(!!authStatus);
}
checkPermissionStatus();
}, [getHasPermission, appStateVisible]);
return (
<CommonLayout h={'100%'} px={'16px'} bgColor={'#FFFFFF'}>
{isAuthorizedNotifications ? (
<AuthorizedNotiScreen />
) : (
<UnAuthorizedNotiScreen />
)}
</CommonLayout>
);
}
export default ExampleScreen;
Reference
'Frontend > React-native' 카테고리의 다른 글
[ReactNative] 유연하고 재사용 가능한 제네릭타입으로 리액트네이티브 내비게이션 관리하기 (0) | 2023.02.19 |
---|---|
[Patch-package] NPM 패키치 간단하게 패치(patch)하는 법 (0) | 2022.12.14 |
[React-native] 앱 개발을 하며 마주한 IOS secureTextEntry 관련 이슈 톺아보기 - 2. 수동으로 패스워드 타입 구현하기 (0) | 2022.12.12 |
[React-native] 앱 개발을 하며 마주한 IOS secureTextEntry 관련 이슈 톺아보기 - 1. 패키지 코드 변경하기 (0) | 2022.12.11 |
[React-native] 리액트 네이티브 Common/Custom Header 관리하기 (0) | 2022.12.10 |
- Total
- Today
- Yesterday
- html
- reactquery
- 리액트네이티브
- 타입스크립트
- css
- 알고리즘자바스크립트
- 무한스크롤
- React
- 자바스크립트 클로저
- github
- 클로저
- 모두를위한컴퓨터과학
- 프로그래머스 베스트앨범 자바스크립트
- cs50
- 프로그래머스
- 자바스크립트
- React Query
- GIT
- 모두를 위한 컴퓨터 과학
- 실전프로젝트
- 리액트
- 자바스크립트 비동기 처리
- 자바스크립트알고리즘
- 백준
- python
- 프로그래머스 자바스크립트
- 네트워크
- network
- 항해99
- javascript
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |