앱이 이미 열려 있는 경우, 딥 링크가 들어오는 링크를 반영하도록 상태를 업데이트해야 합니다.
React Native는 들어오는 링크에 대한 알림을 받기 위해 Linking을 제공합니다. React Navigation은 Linking 모듈과 통합하여 딥 링크를 자동으로 처리할 수 있습니다. 웹에서는 React Navigation이 브라우저의 history API와 통합되어 클라이언트 측에서 URL을 처리할 수 있습니다. 링크 구성 방법에 대한 자세한 내용은 링크 구성을 참조하세요.
React Navigation의 linking 속성을 사용하지 않고, Linking API를 사용하여 직접 딥 링크를 처리하고 거기에서 내비게이션을 할 수 있지만, 이는 linking 속성이 처리하는 많은 엣지 케이스를 고려해야 하기 때문에 훨씬 더 복잡할 것입니다. 따라서 직접 구현하는 것을 권장하지 않습니다.
아래에서는 딥 링크 통합이 작동하도록 필요한 구성에 대해 설명합니다.
Expo 프로젝트 설정
먼저, 앱에 대한 URL 스킴을 지정해야 합니다. 이는 URL에서 :// 이전의 문자열에 해당하며, 스킴이 mychat인 경우 앱으로의 링크는 mychat://이 됩니다. app.json에서 scheme 키 아래에 문자열을 추가하여 스킴을 등록할 수 있습니다:
{
"expo": {
"scheme": "mychat"
}
}
다음으로, 딥 링크 접두사를 얻기 위해 expo-linking을 설치합니다.
npx expo install expo-linking
그런 다음, React Navigation을 구성하여 들어오는 딥 링크를 구문 분석하기 위해 scheme을 사용합니다.
Linking.createURL을 사용하는 이유는 클라이언트 앱인지 독립형 앱인지에 따라 스킴이 달라지기 때문입니다.
app.json에 지정된 스킴은 독립형 앱에만 적용됩니다. Expo 클라이언트 앱에서는 exp://ADDRESS:PORT/--/를 사용하여 딥 링크를 생성할 수 있으며, 여기서 ADDRESS는 종종 127.0.0.1이고 PORT는 종종 19000입니다 - expo start를 실행할 때 URL이 출력됩니다. Linking.createURL 함수는 이를 추상화하여 수동으로 지정할 필요가 없도록 합니다.
유니버설 링크를 사용하는 경우, 접두사에 도메인을 추가해야 합니다.
순수 React Native 프로젝트 설정
iOS 설정
mychat:// URI 스킴을 기반으로 네이티브 iOS 앱을 구성합니다.
프로젝트에 RCTLinking을 링크해야 하며, 이를 위해 여기에 설명된 단계를 따르세요. 들어오는 앱 링크를 수신하려면 프로젝트의 AppDelegate.m에 다음 줄을 추가해야 합니다.
// 파일 상단에 헤더를 추가합니다:
#import <React/RCTLinkingManager.h>
// `@implementation AppDelegate` 내부, `@end` 위에 다음 코드를 추가합니다:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [RCTLinkingManager application:application openURL:url options:options];
}
// `@implementation AppDelegate` 내부, `@end` 위에 다음 코드를 추가합니다:
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
이제 프로젝트 구성에 스킴을 추가해야 합니다.
가장 쉬운 방법은 다음 명령어를 실행하여 uri-scheme 패키지를 사용하는 것입니다:
npx uri-scheme add mychat --ios
수동으로 추가하려면 Xcode에서 프로젝트(예: SimpleApp/ios/SimpleApp.xcworkspace )를 열고, 사이드바에서 프로젝트를 선택한 후 Info 탭으로 이동합니다. "URL Types"로 스크롤하여 하나를 추가합니다. 새 URL 타입에서 식별자와 URL 스킴을 원하는 URL 스킴으로 설정합니다.
하이브리드 React Native 및 네이티브 iOS 애플리케이션 React Navigation을 Swift/ObjC와 React Native 부분을 모두 포함하는 하이브리드 앱(iOS 앱) 내에서 사용하는 경우, Podfile에 기본적으로 설치된 RCTLinkingIOS 서브스펙이 없을 수 있습니다. 이를 추가하려면 Podfile이 다음과 같은지 확인하세요.
pod 'React', :path => '../node_modules/react-native', :subspecs => [
. . . // 다른 서브스펙들
'RCTLinkingIOS',
. . .
]
Android 설정
Android에서 외부 링크를 구성하려면 매니페스트에 새로운 인텐트를 생성할 수 있습니다.
가장 쉬운 방법은 다음 명령어로 uri-scheme 패키지를 사용하는 것입니다.
npx uri-scheme add mychat --android
수동으로 추가하려면 SimpleApp/android/app/src/main/AndroidManifest.xml을 열고 다음 조정을 합니다.
기존 MainActivity에서 launchMode를 singleTask로 설정하여 기존 MainActivity에서 인텐트를 수신합니다(기본값이므로 실제로 변경할 필요가 없을 수 있습니다).
VIEW 유형의 새로운 intent-filter를 MainActivity 항목 내부에 추가합니다.
딥 링크를 테스트하기 전에 에뮬레이터/시뮬레이터/디바이스에 앱을 다시 빌드하고 설치해야 합니다.
iOS에서 테스트하려면 다음 명령어를 실행하세요.
npx react-native run-ios
Android에서 테스트하려면 다음 명령어를 실행하세요.
npx react-native run-android
Expo 관리 워크플로우를 사용하고 Expo 클라이언트에서 테스트하는 경우 앱을 다시 빌드할 필요가 없습니다. 그러나 expo start를 실행할 때 출력되는 올바른 주소와 포트를 사용해야 합니다(위 참조), 예: exp://127.0.0.1:19000/--/.
Expo 앱에서 사용자 정의 스킴으로 테스트하려면 expo build:ios -t simulator 또는 expo build:android를 실행하여 독립형 앱을 다시 빌드하고 생성된 바이너리를 설치해야 합니다.
npx uri-scheme로 테스트
uri-scheme 패키지는 iOS 및 Android에서 딥 링크를 테스트하는 데 사용할 수 있는 명령 줄 도구입니다. 다음과 같이 사용할 수 있습니다.
npx uri-scheme open [your deep link] --[ios|android]
예를 들어
npx uri-scheme open "mychat://chat/jane" --ios
또는 Expo 클라이언트를 사용하는 경우
npx uri-scheme open "exp://127.0.0.1:19000/--/chat/jane" --ios
iOS에서 xcrun으로 테스트
xcrun 명령을 사용하여 iOS 시뮬레이터에서 딥 링크를 테스트할 수 있습니다:
xcrun simctl openurl booted [your deep link]
예를 들어
xcrun simctl openurl booted "mychat://chat/jane"
Android에서 adb로 테스트
adb 명령을 사용하여 Android 에뮬레이터나 연결된 디바이스에서 딥 링크를 테스트할 수 있습니다
adb shell am start -W -a android.intent.action.VIEW -d [your deep link] [your android package name]
예를 들어
adb shell am start -W -a android.intent.action.VIEW -d "mychat://chat/jane" com.simpleapp
또는 Expo 클라이언트를 사용하는 경우
adb shell am start -W -a android.intent.action.VIEW -d "exp://127.0.0.1:19000/--/chat/jane" host.exp.exponent
타사 통합
React Native의 Linking이 딥 링크를 처리하는 유일한 방법은 아닙니다. Firebase Dynamic Links, Branch 등과 같은 다른 서비스를 통합하여 들어오는 링크에 대한 알림을 받으려 할 수도 있습니다. 이를 위해 React Navigation이 들어오는 링크에 대해 구독하는 방법을 재정의해야 합니다. 이를 위해 자체 getInitialURL 및 subscribe 함수를 제공할 수 있습니다.
const linking = {
prefixes: ['myapp://', 'https://myapp.com'],
// 앱을 여는 데 사용된 URL을 가져오는 사용자 정의 함수
async getInitialURL() {
// 먼저, 타사 통합에서 초기 URL을 가져와야 합니다.
// 정확한 사용법은 사용하는 타사 SDK에 따라 다릅니다.
// 예를 들어, Firebase Dynamic Links의 초기 URL을 가져오려면 다음과 같습니다:
const { isAvailable } = utils().playServicesAvailability;
if (isAvailable) {
const initialLink = await dynamicLinks().getInitialLink();
if (initialLink) {
return initialLink.url;
}
}
// 기본 딥 링크 처리를 원할 경우
const url = await Linking.getInitialURL();
return url;
},
// 들어오는 링크에 구독하는 사용자 정의 함수
subscribe(listener) {
// Firebase Dynamic Links의 들어오는 링크를 수신합니다.
const unsubscribeFirebase = dynamicLinks().onLink(({ url }) => {
listener(url);
});
// 딥 링크의 들어오는 링크를 수신합니다.
const linkingSubscription = Linking.addEventListener('url', ({ url }) => {
listener(url);
});
return () => {
// 이벤트 리스너 정리
unsubscribeFirebase();
linkingSubscription.remove();
};
},
config: {
// 딥 링크 구성
},
};
위 예제와 유사하게 getInitialURL 및 subscribe 옵션을 사용하여 초기 URL을 가져오고 새로운 들어오는 URL에 구독할 수 있는 모든 API를 통합할 수 있습니다.