React Native에서 딥링크 처리 시 iOS/Android 분기 처리

문제 상황

마케팅 캠페인을 위한 딥링크 기능을 구현하던 중, iOS와 Android에서 앱 상태에 따라 딥링크가 다르게 처리되는 문제를 발견했다. Linking.getInitialURL()Linking.addEventListener()를 함께 사용했는데, 특정 상황에서 중복 처리되거나 아예 동작하지 않는 케이스가 있었다.

플랫폼별 동작 차이

iOS

  • 앱이 완전히 종료된 상태: getInitialURL()만 호출됨
  • 백그라운드 상태: url 이벤트만 발생

Android

  • 앱이 완전히 종료된 상태: getInitialURL() + url 이벤트 둘 다 발생 (중복)
  • 백그라운드 상태: url 이벤트만 발생

해결 방법

중복 처리를 방지하기 위해 타이머와 URL 캐싱을 조합했다.

import { Linking, Platform } from 'react-native';

let lastProcessedUrl = null;
let urlProcessTimeout = null;

const processDeepLink = (url) => {
  if (lastProcessedUrl === url) return;
  
  lastProcessedUrl = url;
  
  if (urlProcessTimeout) {
    clearTimeout(urlProcessTimeout);
  }
  
  urlProcessTimeout = setTimeout(() => {
    lastProcessedUrl = null;
  }, 1000);
  
  // 실제 딥링크 처리 로직
  handleDeepLink(url);
};

useEffect(() => {
  // 앱 시작 시 초기 URL 확인
  Linking.getInitialURL().then((url) => {
    if (url) {
      processDeepLink(url);
    }
  });
  
  // 이벤트 리스너 등록
  const subscription = Linking.addEventListener('url', ({ url }) => {
    processDeepLink(url);
  });
  
  return () => {
    subscription.remove();
    if (urlProcessTimeout) {
      clearTimeout(urlProcessTimeout);
    }
  };
}, []);

추가 고려사항

Android에서 launchModesingleTask로 설정하면 중복 인스턴스 생성을 방지할 수 있다. AndroidManifest.xml에서 설정했다.

<activity
  android:launchMode="singleTask"
  android:configChanges="keyboard|keyboardHidden|orientation|screenSize">

결과적으로 두 플랫폼 모두에서 안정적으로 딥링크가 처리되었고, QA 과정에서도 중복 호출 이슈가 발생하지 않았다.