딥링크, URL 스킴, 유니버셜 링크, 다이나믹 링크 뭐가 뭔데?

2025. 10. 26. 21:45·내게 필요한 개발 공부

어떤 버튼을 눌렀을 때 특정 앱이 열리는 기능은 우리에게 익숙합니다. 그런데 도대체 이 기능을 뭐라고 불러야 할까요? 어디서는 딥링크, 어디서는 URL 스킴, 유니버셜 링크, 다이내믹 링크 등 다양한 용어가 들려오는데 이름만 다른 걸까요? 혹은 정말 다른 기능들일까요?

 

오늘은 iOS 앱 개발 관점에서 알쏭달쏭 헷갈리는 용어들에 대해 확실하게 이해해 보는 시간을 가져보겠습니다!

 

사실은 모두 딥링크

이것저것 단어가 많지만 사실은 모두 '딥링크'라고 할 수 있습니다. URL 스킴, 유니버셜 링크, 다이나믹 링크 등 "앱 내 특정 페이지로 바로 연결되는 모든 기술"은 딥링크라는 큰 기술 카테고리에 묶인다고 이해하면 됩니다.

딥링크 == 일반적인 용어(대 카테고리)

 

가장 전통적인 방법, URL Scheme

URL Scheme은 딥링크의 가장 전통적인 방식입니다. 앱이 고유하게 등록한 URL 형식을 사용해 앱을 실행하는 방식으로 `myphotoapp:albumname?name="albumname"`과 같은 구조로 사용됩니다.

  • 다른 앱의 실행을 요청하거나 간단한 데이터 전달 가능.
  • 앱이 설치되어 있을 때만 작동.
  • iOS 9.0 이전까지의 표준 딥링크 방식.
  • 앱에 잠재적인 공격 경로를 제공할 수 있기 때문에, 매개변수의 유효성을 검사하고 잘못된 URL은 삭제해야 함.(특히 개인정보를 포함하는 것은 위험!)
  • 앱스토어에서 Scheme의 고유성을 보장해주지 않기 때문에 다른 곳에서 무단 사용할 수 있음.(이 때문에 애플은 아래에서 후술 할 유니버설 링크 사용을 권장함.)

애플에서 제공하는 URL Scheme 공식 문서, Defining a custom URL scheme for your app를 참고해 직접 URL Scheme을 가지고 놀아보겠습니다.

 

1. 내 앱으로 이동할 수 있는 URL Scheme 추가해 보기

Xcode의 Targets - Info - URL Types에 새로운 URL Scheme을 추가해 보겠습니다.

가장 첫 번째 필드인 Identifier에는 다른 앱과 내 앱을 구분하는 데 사용될 식별자를 지정합니다. 애플 공식문서에서는 고유성을 보장하기 위해 회사 도메인(저의 경우 개발자 이름!)과 앱 이름을 포함하는 역방향 DNS 문자열 지정을 권장합니다.(하지만 근본적으로 다른 앱과 동일한 Scheme 등록을 막을 수는 없다고 합니다 🫩)

 

두 번째 필드인 URL Schemes에는 딥링크 URL 앞에 들어갈 접두사를 지정합니다. 저의 경우 앱 이름인 'poporazzi'를 지정해 주었으며, 앞으로 `poporazzi://`의 형태로 앱이 열릴 수 있게 만들어 줄 수 있을 겁니다!

 

여기서 한 가지 더 주의해야 할 점은, 일부 URL Scheme은 애플 시스템 전용으로 예약되어 있습니다. 기본 메일, 전화, 지도, 음악 앱 등이 이에 포함되어 있으며 자세한 내용은 App URL Scheme Reference 페이지에서 확인할 수 있습니다.(한 마디로 애플이 미리 등록해 놓은 URL Scheme은 사용 못 한다~ 얘기입니닷)

 

(요 아래부터는 거의 사용하지 않으나 어떤 건지 알아보는 목적으로 쓱 훑으면 좋지 않을까 싶습니다.)

 

세 번째 필드인 Icon은 URL Scheme과 연결된 문서 아이콘을 지정합니다. 딥링크로 열 수 있는 파일이나 문서 등을 표시할 때 사용된다고 하는데, 일반적인 경우엔 사용하지 않는다고 합니다.

 

네 번째 필드인 Role은 앱이 URL을 어떻게 처리하는지 정의합니다. 지정할 수 있는 옵션은 Viewer(읽기 전용), Editor(읽기/쓰기), None(역할 정의 X) 3가지로 나뉘는데 식별을 위한 요소일 뿐이지 기능적인 영향은 없다고 합니다.

 

그 아래 Additional url type properties에는 커스텀 속성을 정의할 수 있습니다. URL Scheme의 버전 정보나 설명 등을 추가할 수 있다고 하는데 이 또한 기능적인 영향은 없어 대부분의 딥링크 구현에선 비워도 무방합니다.

 

2. URL Scheme으로 내 앱 열어보기

요렇게 만들어본 URL Scheme으로 제 앱을 열어봐야겠죠? 위에서도 언급했듯, URL Scheme은 앱이 설치되어 있을 때만 동작하기 때문에 꼭 새로 빌드 후 테스트 해보는 걸 잊지 않으며, Safari에 URL Scheme을 입력해 보면 아주 잘 열리는 것을 확인할 수 있습니다!

위에서 지정한 접두사로 딥링크 입력

++ 만약 앱이 설치되어 있지 않다면, URL Scheme을 찾을 수 없기 때문에 Safari에서 유효하지 않은 주소라고 알려주게 됩니다.

 

3. URL Scheme으로 들어온 이벤트 핸들링하기

URL Scheme으로 들어온 이벤트에 대해 특정 행동을 하거나, URL 매개변수를 파싱해 특정 화면으로 이동시키고 싶은 경우엔 `SceneDelegate`의 LifeCycle에서 이벤트를 핸들링할 수 있습니다.

// 1. 앱이 실행되지 않은 상태에서 URL Scheme이 실행될 때
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    if let url = connectionOptions.urlContexts.first?.url {
        // 여기서 핸들링!
    }
}

// 2. 앱이 이미 실행 중일 때 딥링크가 열릴 때
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    if let url = URLContexts.first?.url {
        // 여기서 핸들링!
    }
}

여기서 옵셔널 바인딩 되는 `URL` 타입을 가지고 host, path, query 등을 추출해 다양한 URL Scheme에 따라 분기 처리를 하면 되겠죠? 주의해야 할 점은, 앱의 실행 여부에 따라 실행되는 SceneDelegate 내 메서드가 다르기 때문에 목적에 따라 구현해야 함을 유념해야 합니다.

 

4. 내 앱에서 다른 앱의 URL Scheme 열기

`UIApplication`에서 제공하는 `open` 함수를 사용해 다른 앱의 URL Scheme을 열 수 있습니다.

if let url = URL(string: "poporazzi://") {
    UIApplication.shared.open(url) { result in
        if result {
           // URL Scheme 실행 결과 handler
        }
    }
}

 

현재 표준이 된 유니버셜 링크 Universal Link

유니버셜 링크는 Apple의 공식 딥링크 기술입니다.(안드로이드의 App Link와 대응) 위에서 소개한 URL Scheme의 한계점인 앱 설치의 필요성, 고유성 보장, 보안 등의 문제를 해결해 줄 수 있어 현재 가장 보편적으로 사용되고 있습니다.

  • https://myphotoapp.com/name/albumname 형식으로 사용.(일반 HTTPS 형식을 따름)
  • 앱 미설치 시 웹사이트로 이동할 수 있게 처리 가능.
  • iOS 9.0 이후 표준 딥링크 방식.
  • 앱의 Bundle Id를 미리 특정 도메인의 웹사이트에 등록하는 방식으로, 고유성을 보장할 수 있음.
  • 일반 웹 URL이기 때문에 SEO 최적화.
  • Apple이 서버 인증서(AASA)로 검증해 보안 향상.

이렇게 보면 URL Scheme을 사용하지 않을 이유가 없어 보이지만, 도메인과 서버 설정이 필수적이기 때문에 구현과 테스트가 어렵다는 단점도 존재합니다. 그래서 작은 앱을 만들 때는 URL Scheme을 사용하는 것이 효율적일 수도 있겠습니다!

 

클라이언트 입장에서 유니버셜 링크를 테스트해보고 싶기 때문에 간단하게 Vercel을 사용해 진행해 보겠습니다.(이 과정에서 서버 관련 지식이 한참 부족하다 보니 좀 헤매버렸습니다,,)

 

1. 서버  - AASA(apple-app-site-association) 파일 추가

유니버셜 링크를 사용하기 위해 필수적인 것이 도메인과 서버 설정입니다. 이 때 도메인 정보가 포함된 JSON 파일인 AASA(apple-app-site-association) 파일을 서버에 업로드 해야 해당 파일을 확인 후 앱을 실행시켜주는 프로세스입니다.

 

AASA 파일 구성 시 중요한 부분은 appID와 components(path)입니다. app ID에는 {Team-ID}.{Bundle-ID} 로 구성된 값을 넣어주고, components에는 이동할 경로를 명시합니다.

{
  "applinks": {
    // 유니버셜 링크에서는 사용하지 않지만 빈 배열로 명시 필요
    "apps": [],
    // 웹사이트에서 이동 가능한 앱 목록.
    "details": [
      {
        // {Team-ID}.{Bundle-ID}
        "appIDs": ["9XG4S4XZWN.com.thinkyside.poporazzi"],
        // 웹사이트 경로
        "components": [
          {
            "/": "*"
          }
        ]
      }
    ]
  }
}

서버 구성 시 확인해야 할 점은 HTTPS와 SSL 지원 여부입니다. 애플의 보안 정책 때문인지 기본적으로 챙길 수 있는 것들은 체크가 필요할 듯 합니다! 또한 AASA 파일은 웹사이트 내 표준화된 메타데이터나 설정 파일을 저장하는 디렉토리인 `.well-known`에 추가되어야 합니다.

 

2. 클라이언트 - Associated Domains(Capabilities) 설정

클라이언트(iOS 개발자)는 Xcode를 이용해 Associated Domains Capabilities를 설정해 주어야 합니다. Targets - Signing & Capabilites 탭에서 + Capability 버튼을 클릭합니다.

Targets - Signing & Capabilites 탭에서 + Capability 버튼 클릭

이후 유니버셜 링크를 설정해 줄 수 있는 Capability인 Associated Domains를 클릭해 추가해줍니다.

Associated Domains 검색 후 추가

요렇게 추가된 Associated Domains 아래 Domains Row에 우리의 도메인을 추가하면 완료입니다. 아래 추가할 도메인은 `applinks:{YOUR_DOMAIN}` 형식으로 작성되어야 합니다. 저는 vercel에서 내려준 도메인을 입력해주었습니다.

applinks:{YOUR_DOMAIN} 추가

이제 테스트 해보면! 딥링크가 아주 잘 동작하는 것을 확인할 수 있습니다.(만약 딥링크가 동작을 안한다면 10~20분 정도 기다려본 후 다시 시도해보는게 도움이 될 수 있습니다! Apple CDN이 캐시를 업데이트 하는 시간이 필요하다고 하네요,,, >> 이것 때문에 다른 곳에서 삽질 엄청함)

 

3. 유니버셜 링크로 들어온 이벤트 핸들링하기

유니버셜 링크 또한 `SceneDelegate`에서 이벤트를 핸들링할 수 있는데 `URLContext`를 이용했던 URL Scheme과 달리, `NSUserActivity`를 이용해야 합니다.

 

NSUserActivity는 특정 시점의 앱 상태를 나타내는 객체로, 사용자가 수행한 작업에 대한 정보를 캡처합니다. 보통 그 아래 속성인 `webPageURL`을 이용해 URL 타입을 반환 받고 path, query에 따라 분기 처리를 진행하면 됩니다.

// 1. 앱이 실행되지 않은 상태에서 URL Scheme이 실행될 때
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    if let url = connectionOptions.userActivities.first?.webpageURL {
        // 여기서 핸들링!
    }
}

// 2. 앱이 이미 실행 중일 때 딥링크가 열릴 때
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
    if let url = userActivity.webpageURL {
        // 여기서 핸들링!
    }
}

앱이 실행되지 않을 때는 URL Scheme과 마찬가지로 `willConnectTo` Delegate 메서드를 이용하면 되지만, 앱이 이미 실행 중일 때는 `continueUserActivity` Delegate 메서드를 사용해야 한다는 점을 체크해주세요!

 

다른 앱의 유니버셜 링크를 여는 방법은 URL Scheme과 동일합니다~!

if let url = URL(string: "https://poporazzi.vercel.app/home") {
    UIApplication.shared.open(url)
}

 

하나의 링크로 여러 플랫폼을 관리하는 똑똑한 다이나믹 링크 Dynamic Link

마지막은 다이나믹 링크입니다. 보통 앱 개발 시 iOS와 안드로이드 OS를 지원하게 되는데, 유니버셜 링크의 경우 애플의 독자적인 딥링크 기술이기 때문에 안드로이드에서의 딥링크는 앱 링크(App Link)로 별도 구현이 필요합니다.

 

이는 딥링크가 새로 추가될 때마다 작업량도 두배, 수정될 때도 체크해야 할 포인트가 두배가 되기 때문에 유지보수성이 떨어질 수 밖에 없게 됩니다. 이를 해결해줄 수 있도록 하나의 링크로 모든 OS에 대한 딥링크를 연결해주는 AppsFlyer, Branch.io 등이 제공하는 것이 다이나믹 링크입니다.

 

다이나믹 링크를 지원하는 서비스에 따라 조금씩 다르지만, 크게 아래와 같은 기능들을 제공합니다.

  • 하나의 링크로 iOS/Android 멀티 플랫폼 딥링크 지원.(각각의 기술로 컨버팅)
  • Deferred Deep Link 기술 지원.(앱 미설치 사용자에게도 딥링크 정보를 전달할 수 있는 기술, 이건 별도 포스팅 해보면 좋을듯!)
  • 링크 단축 기능 제공.
  • 링크 클릭 수, 앱 설치 전환율, 플랫폼별 통계 등 데이터 제공.
  • A/B 테스팅 지원.

다이나믹 링크의 핵심은, 비즈니스 차원에서 유지보수 비용도 줄이고 다양한 데이터들을 볼 목적으로 사용하는 서비스 차원의 개념이라는 것입니다. 또한 iOS의 경우 다이나믹 링크도 실제 동작은 결국 유니버셜 링크를 사용하기 때문에, 구현 방법은 위에서 서술한 방식과 동일합니다! 😇

 

최종 정리

기능 URL Scheme Universal Link Dynamic Link
형식 myapp:// https://myapp.com https://myapp.page.link
iOS 버전 iOS 9.0 미만 iOS 9.0 이상 iOS 9.0 이상
앱 미설치 시 동작  ❌ 경고 발생 ✅ 웹페이지 이동  ✅ 스토어→ 설치→ 딥링크(Deferred)
도메인 필요 여부 ❌ 불필요  ✅ 필수  ✅ 필수(서비스가 제공해줌)
서버 설정 ❌ 불필요 ✅ 필수(AASA 파일 추가) ❌ 서비스가 관리
고유성 보장 ❌ 보장하지 않음  ✅ 도메인으로 보장  ✅ 서비스가 보장
보안  ⚠️ 낮음  ✅ 높음(Apple 검증)  ✅ 높음
크로스플랫폼 ❌ OS별 구현 ❌ OS별 구현  ✅ 하나로 관리 가능
추천 용도 앱 간 통신, 간단한 앱 표준 딥링크, 비즈니스 레벨의 앱 유지보수, 마케팅이 필요한 앱

 

저작자표시 (새창열림)

'내게 필요한 개발 공부' 카테고리의 다른 글

함수와 메서드는 다르다.  (4) 2025.08.01
Task는 항상 부모 Context를 상속 받을까?  (5) 2025.07.22
멀티태스킹과 멀티프로세싱, 비슷한듯 다른 두 개념  (0) 2025.03.17
안전한 놀이터 샌드박스 알아보기  (2) 2025.02.26
iOS에서 OS 뜯어보기  (0) 2025.02.26
'내게 필요한 개발 공부' 카테고리의 다른 글
  • 함수와 메서드는 다르다.
  • Task는 항상 부모 Context를 상속 받을까?
  • 멀티태스킹과 멀티프로세싱, 비슷한듯 다른 두 개념
  • 안전한 놀이터 샌드박스 알아보기
thinkyside
thinkyside
스스로에게 솔직해지고 싶은 공간
  • thinkyside
    또 만드는 한톨
    thinkyside
  • 전체
    오늘
    어제
    • 모아보기 (70)
      • 솔직해보려는 회고 (1)
      • 꾸준히 글쓰기 (10)
      • 생각을 담은 독서 (8)
      • 내게 필요한 개발 공부 (25)
      • 실무 내용 내껄로 만들.. (4)
      • 트러블슈팅 (4)
      • 프로젝트 일지 (9)
      • 개발 서적 (3)
      • 취준 (3)
      • 대외활동 (2)
      • UXUI (1)
  • hELLO· Designed By정상우.v4.10.3
thinkyside
딥링크, URL 스킴, 유니버셜 링크, 다이나믹 링크 뭐가 뭔데?
상단으로

티스토리툴바