Skip to main content
Version: Next

링크 연결

Linking은 앱으로 들어오거나 나가는 링크를 처리할 수 있는 일반적인 인터페이스를 제공한다.

모든 링크(URL)는 URL 스킴을 가진다. 예를 들어, https://http://로 시작하는 웹사이트에서 http가 URL 스킴이다. 이를 간단히 스킴이라고 부른다.

https 외에도 mailto 스킴을 접해본 적이 있을 것이다. mailto 스킴이 포함된 링크를 열면, 운영체제는 설치된 메일 애플리케이션을 실행한다. 마찬가지로 전화 걸기나 SMS 보내기와 같은 스킴도 존재한다. 내장 URL 스킴에 대해 더 알아보자.

mailto 스킴을 사용하는 것처럼, 커스텀 URL 스킴을 통해 다른 애플리케이션으로 연결할 수도 있다. 예를 들어, Slack에서 Magic Link 이메일을 받으면, Launch Slack 버튼은 slack://secret/magic-login/other-secret와 같은 href를 가진 앵커 태그다. Slack과 마찬가지로, 운영체제에 커스텀 스킴을 처리하도록 지정할 수 있다. Slack 앱이 열리면, 앱을 열 때 사용된 URL을 받는다. 이를 딥 링킹이라고 부른다. 앱으로 딥 링크 가져오기에 대해 더 알아보자.

커스텀 URL 스킴은 모바일에서 앱을 여는 유일한 방법이 아니다. 예를 들어, 모바일에서 열릴 링크를 이메일로 보내려고 할 때, 커스텀 URL 스킴을 사용하는 것은 이상적이지 않다. 사용자가 데스크톱에서 이메일을 열면 링크가 작동하지 않기 때문이다. 대신 https://www.myapp.io/records/1234546과 같은 표준 https 링크를 사용해야 한다. 모바일에서는 이러한 링크가 앱을 열도록 설정할 수 있다. Android에서는 이를 Deep Links라고 부르고, iOS에서는 Universal Links라고 한다.

내장 URL 스키마

소개에서 언급했듯이, 모든 플랫폼에 존재하는 핵심 기능을 위한 몇 가지 URL 스키마가 있다. 다음은 모든 것을 포함하지는 않지만 가장 일반적으로 사용되는 스키마를 다룬다.

스키마설명iOSAndroid
mailto메일 앱을 열기, 예: mailto: support@expo.io
tel전화 앱을 열기, 예: tel:+123456789
smsSMS 앱을 열기, 예: sms:+123456789
https / http웹 브라우저 앱을 열기, 예: https://expo.io

딥 링크 활성화

앱에서 딥 링크를 활성화하려면 아래 가이드를 참고한다:

안드로이드에서 딥 링크를 지원하는 방법은 앱 콘텐츠에 딥 링크 활성화 - 딥 링크를 위한 인텐트 필터 추가를 참고한다.

기존 MainActivity 인스턴스에서 인텐트를 받으려면, AndroidManifest.xml에서 MainActivity의 launchModesingleTask로 설정한다. 자세한 내용은 <activity> 문서를 참고한다.

xml
<activity
android:name=".MainActivity"
android:launchMode="singleTask">

딥 링크 처리 방법

앱을 열어주는 URL을 처리하는 방법은 크게 두 가지가 있다.

앱이 이미 실행 중인 경우, 앱이 포그라운드로 전환되고 Linking 'url' 이벤트가 발생한다.

이 이벤트는 Linking.addEventListener('url', callback)를 사용해 처리할 수 있다. 이 메서드는 연결된 URL을 포함한 callback({url})을 호출한다.

앱이 아직 열려 있지 않다면, 앱을 열고 initialURL로 URL을 전달한다.

이러한 이벤트는 Linking.getInitialURL()로 처리할 수 있다. 이 메서드는 URL이 있다면 해당 URL로 resolve되는 Promise를 반환한다.

예제

링크 열기와 딥 링크 (유니버설 링크)

커스텀 설정 열기

딥 링크 가져오기

인텐트 전송 (안드로이드)

참조

메서드

addEventListener()

tsx
static addEventListener(
type: 'url',
handler: (event: {url: string}) => void,
): EmitterSubscription;

url 이벤트 타입을 수신하고 핸들러를 제공하여 링크 변경에 대한 핸들러를 추가한다.

canOpenURL()

tsx
static canOpenURL(url: string): Promise<boolean>;

설치된 앱이 주어진 URL을 처리할 수 있는지 여부를 확인한다.

이 메서드는 Promise 객체를 반환한다. 주어진 URL을 열 수 있는지 여부가 결정되면, Promise가 이행되며 첫 번째 매개변수로 URL을 열 수 있는지 여부가 반환된다.

안드로이드에서 URL을 열 수 있는지 확인할 수 없거나, Android 11 (SDK 30)을 타겟으로 할 때 AndroidManifest.xml에 관련 인텐트 쿼리를 지정하지 않은 경우 Promise는 거부된다. iOS에서도 마찬가지로, Info.plistLSApplicationQueriesSchemes 키에 특정 스킴을 추가하지 않으면 Promise가 거부된다 (아래 참조).

매개변수:

이름타입설명
url
필수
string열려는 URL.

웹 URL의 경우 프로토콜("http://", "https://")을 반드시 지정해야 한다!

이 메서드는 iOS 9+에서 제한 사항이 있다. 공식 Apple 문서에 따르면:

  • 앱이 이전 버전의 iOS에 연결되었지만 iOS 9.0 이상에서 실행 중인 경우, 이 메서드를 최대 50번까지 호출할 수 있다. 이 제한에 도달하면 이후 호출은 항상 false로 해결된다. 사용자가 앱을 재설치하거나 업그레이드하면 iOS가 이 제한을 재설정한다.

iOS 9부터는 Info.plistLSApplicationQueriesSchemes 키를 제공해야 하며, 그렇지 않으면 canOpenURL()은 항상 false로 해결된다.

Android 11 (SDK 30)을 타겟으로 할 때는 AndroidManifest.xml에서 처리하려는 스킴에 대한 인텐트를 지정해야 한다. 일반적인 인텐트 목록은 여기에서 확인할 수 있다.

예를 들어 https 스킴을 처리하려면 매니페스트에 다음을 추가해야 한다:

<manifest ...>
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https"/>
</intent>
</queries>
</manifest>

getInitialURL()

tsx
static getInitialURL(): Promise<string | null>;

앱 실행이 딥 링크에 의해 트리거된 경우, 해당 링크의 URL을 반환한다. 그렇지 않으면 null을 반환한다.

안드로이드에서 딥 링크를 지원하려면 https://developer.android.com/training/app-indexing/deep-linking.html#handling-intents를 참고한다.

원격 JS 디버깅이 활성화된 상태에서는 getInitialURLnull을 반환할 수 있다. 정상적인 동작을 보장하려면 디버거를 비활성화한다.

openSettings()

tsx
static openSettings(): Promise<void>;

Settings 앱을 열고, 해당 앱에 커스텀 설정이 있다면 이를 표시한다.

openURL()

tsx
static openURL(url: string): Promise<any>;

설치된 앱 중 하나를 사용해 주어진 url을 열려고 시도한다.

위치 정보("geo:37.484847,-122.148386" - Android 또는 "https://maps.apple.com/?ll=37.484847,-122.148386" - iOS), 연락처, 또는 설치된 앱으로 열 수 있는 다른 URL도 사용할 수 있다.

이 메서드는 Promise 객체를 반환한다. 사용자가 열기 대화 상자를 확인하거나 URL이 자동으로 열리면 Promise가 이행된다. 사용자가 열기 대화 상자를 취소하거나 URL에 대해 등록된 애플리케이션이 없으면 Promise가 거부된다.

매개변수:

이름타입설명
url
필수
string열려는 URL

시스템이 지정된 URL을 열 수 없으면 이 메서드는 실패한다. HTTP(S)가 아닌 URL을 전달할 경우, 먼저 canOpenURL()을 확인하는 것이 좋다.

웹 URL의 경우, 프로토콜("http://", "https://")을 반드시 설정해야 한다!

이 메서드는 시뮬레이터에서 다르게 동작할 수 있다. 예를 들어, iOS 시뮬레이터에서는 전화 앱에 접근할 수 없기 때문에 "tel:" 링크를 처리할 수 없다.

sendIntent()
Android

tsx
static sendIntent(
action: string,
extras?: Array<{key: string; value: string | number | boolean}>,
): Promise<void>;

안드로이드 인텐트를 추가 데이터와 함께 실행한다.

매개변수:

이름타입
action
필수
string
extrasArray<{key: string, value: string | number | boolean}>