앱을 제작하는 과정은 풀어야 하는 문제의 연속이다. 어김없이 문제가 발생했던 날이었다.
앱에서 뒤로가기를 했을 때 특정 페이지가 보이는 개발을 했어야 했다.
특정 상품 페이지를 보여준 후 사용자가 뒤로가기를 한다면, 해당 상품에 관련된 기획전을 보여주고 싶었던 것 같다.
웹에서는 이 것이 개발 되어 있었다.
url 에 fallback 이라는 파라미터가 있고 해당 파라미터에 사용자가 어디로 가야 하는지를 명시해둔 것이다.
(지금 생각해보면 엄밀히 얘기해서 fallback 은 아니긴 하다)
앱은 뒤로가기를 할 때 특정 스크린을 끼워주어야 한다. 나름 쉽게 설명하면 이렇다.
- 앱의 각 화면을 Screen이라고 부르고, Stack(쌓는 구조) 또는 Tab(하단 메뉴) 등 여러 방식으로 화면을 전환한다.
- 서랍처럼 위에 쌓는 구조이므로 특정 페이지로 이동하는 것은, 새 화면을 하나 더 얹는 것이다.
- 뒤로가기를 하면 해당 화면은 없애고 뒤에 있던 화면을 하나 꺼내는 것이다.
첫 번째로 생각난 방법은 이처럼 스크린을 끼워주는 방식이었다.
사용자가 뒤로가기를 한다-> 클릭 시 url 에 fallback 이 있으면 스크린을 넣어준다 -> 우리가 의도한 스크린을 사용자가 본다
하지만 이 방식은 문제가 있었으니, 앱에서는 뒤로가기가 세가지 방식이 있다는 것이었다.
- 아이콘을 클릭해서 뒤로가기
- 안드로이드 : 뒤로가기 (물리적인 버튼) 을 누르기
- IOS : 좌측에서 우측으로 슬라이드
이 것이 뒤로가기 아이콘 버튼이고, 여기에 뒤로가기 기능이 아닌 특정 페이지로 이동하게만 해주면 쉽게 개발되었다.
다른 뒤로가기 방식은 막기 어려웠다. 이 때에는 클릭했을 때 뒤로가기 페이지를 끼워주는 것이 아닌, 뒤로가기를 감지해서 페이지를 끼워주는 수 밖에 없었다.
한가지 또 큰 문제에 봉착했다. 안드로이드에서 back 을 클릭하는 것은 우리가 감지할 수 있지만 아이폰에서 back 을 하는 것을 감지하기가 어렵다는 것이었다. react native 에서는 이와 같이 하면 안드로이드에서 감지가 가능하다.
import { BackHandler } from 'react-native';
BackHandler.addEventListener('hardwareBackPress', onAndroidBackPress);
즉, 안드로이드에서만 사용자가 뒤로가기를 했을 시 특정 페이지를 보여줄 수 있게 되는 것이다.
IOS에서 뒤로가기를 감지하려고 많은 고민을 했지만 실패했다.
예를 들어서 navigation 이 작동하면 (즉 앱 내에서 url 이 바뀌면) 이전 url 에 fallback 이 있는지를 체크해서 있다면 페이지를 추가하는 방식으로 가려고 했다. 이 방식은 나의 동료인 찰리가, url 에 fallback 이 완전히 삭제되거나 하는 보장이 없을 수 있어, 부작용이 발생할 수 있다고 리뷰를 주었다.
생각해보니 맞는 말이었다. 지금이야 괜찮아보이지만 이는 나중에 가서 분명히 부작용이 발생할 수 있는 방식이었다. (navigation 때마다 특정 로직을 발생시키는 것은 삼가는게 좋은 것 같다.)
코드를 모두 삭제하고 창의적인 발상을 하기 위해 산책을 했다. 나는 방법이 없다고 생각할 때 이따금 산책을 하곤 한다.
그러다가 든 생각이, 굳이 뒤로가기를 할 때 페이지를 넣어주어야만 할까 하는 생각이 들었다. 생각해보면 페이지를 열 때 url 에 fallback 이 있으면 페이지를 추가해주어도 된다고 생각했다.
이 것이 가능한 것은 해당 로직은 유저가 딥링크를 클릭할 때에만 발생하면 되는 것이기 때문이었다. 즉, 이 로직은 단 한번만 실행된다는 것이며 그만큼 부작용이 없다는 뜻이었다. 유저가 딥링크를 여는 순간에만 로직을 발생시키면 된다.
딥링크란 스마트폰 앱을 열 때 특정 화면이나 정보로 바로 연결되게 하는 기술이다.
로직을 이렇게 작성했다.
// 화면을 넣어주는 코드
RootNavigationRef.current.dispatch(
CommonActions.navigate(routeName, params)
);
// 딥링크를 열어주는 코드
queueMicrotask(() => {
listener(deeplink);
});
이렇게 하면 url 을 분석하여 네이티브 페이지 스크린에 내가 원하는 페이지를 넣으면서 시작할 수 있다.
해당 페이지에서 어떤 뒤로가기를 하더라도 유저는, 뒤로가기 대신에 내가 원하는 페이지로 가게 되는 것이다.
(아이콘을 눌러 뒤로 가든지, 안드로이드, 아이폰 모두)
코드 중에서 miscro task queue 를 사용한 부분이 있는데 이는 navigate 이후에 딥링크를 열도록 순서를 조정하려고 한 것이다.
결과 코드는 몇 줄 안되지만 고민은 많이 했던 개발이어서 이렇게 블로그에 남겨둔다.
'Develop' 카테고리의 다른 글
Jest 테스트 코드의 효과와 예시 연구 (0) | 2024.07.20 |
---|---|
lazy loading으로 Entry Point File 크기 줄이는 방법 연구 (0) | 2024.07.20 |
React context 대신 Event bus를 사용해 렌더링 개선하는 방법 조사 (2) | 2024.07.20 |
drag event 성능 개선을 위한 JS web worker 사전 조사 (0) | 2024.07.20 |
React : performamce, profiler를 통한 성능 개선 측정하기 (drag & drop, state refactoring) (0) | 2024.07.20 |