기어가더라도 제대로

[Xcode] UniversalLink 본문

Xcode, build, etc

[Xcode] UniversalLink

Damagucci-juice 2024. 8. 9. 12:36

⚠️ 이 게시글은 iOS 13 이상 기준으로 작성됨

⚠️ Nginx 기준 (Apache → https://gist.github.com/anhar/6d50c023f442fb2437e1 참조)

⚠️ 웹 서버가 redirection을 하면 적용 안됨

사용자가 URL 링크를 클릭했을 때 앱이 설치되어 있으면, 앱 내의 특정 부분으로 이동하는 링크

앱이 설치되어있지 않으면 웹 주소가 있다면 웹 주소로 가는 링크

구) URI Scheme

비슷한 기능을 하던 스킴이 있는데, 프로토콜 부분에 자기네 서비스가 정의한 식별자값을 넣어서 앱을 확인하고 들어가는 링크

SomeApp://<#Link#>

SomeApp 부분이 앱을 식별하는 부분인데 앱이 많으니까 겹치는 경우가 발생하고

한편으론 악의적으로 다른 앱과 겹치게 선언하면 그 앱으로 가는 흐름을 해적 앱으로 끌어 갈 수도 있는 문제가 발생해서 이런 문제점을 해결하고자 Universal Link 등장

현) Universal Link

https://<#Link#>

위 주소로 접근하면 앱으로 이동

그러면 저 URL 주소로 접근해서 어떻게 모바일로 라우팅하는가? 이게 Universal Link의 핵심

웹서버에 apple-app-site-association 파일을 추가

웹 서버로 접근했을 때, 저 파일을 보고 앱도 있겠군 하고 앱으로 이동

앱에서 “어떻게 하라”는 라우팅 로직을 선언


서버에서 작업

  • apple-app-site-association 을 웹 서버에 심기

자신 회사의 웹 서버의 루트 디렉토리 혹은 /.well-known/ 디렉터리에 저장

{
  "applinks": {
      "details": [
           {
             "appIDs": [ "<APP IDENTIFIER>.<BUNDLE IDENTIFIER>" ],
             "components": [
                {
                        "/": "*"
                }
             ]
           }
       ]
   },
   "webcredentials": {
      "apps": [ "<APP IDENTIFIER>.<BUNDLE IDENTIFIER>" ]
   }
}

⚠️ 주의사항

  • appIDs에 BundleIdentifier 앞 부분엔 App Identifier를 넣는게 맞다.

  • 키-값 선언하는 부분 모두 쌍따옴표
  • Apple CDN이 웹 서버를 보고 변화를 감지하는데 시간이 걸린다.
  • 웹 서버의 기본 라우팅 원칙을 수정하기 (nginx)

file path: /etc/nginx/site-available/default

이 곳에서 적절하게 선언해주면 됨

server {
   ...
   # 만약 association domain 파일이 / 밑에 있다면
   location /apple-app-site-association {
      default_type application/json;
   }

   # 만약 association domain 파일이 /.well-known 밑에 있다면
   location /.well-known/apple-app-site-association {
      default_type application/json;
   }
}

Xcode에서 작업

⚠️ 사전에 Provisioning Profile에서 Associated Domains 권한을 부여받은 프로필이 필요

  • Entitlement 적용

App Target > Signing & Capabilities > + Capability > Associated Domains 추가

  • 앱의 시작점에서 Universal Link 다루기
    • AppDelegate or SceneDelegate에서 한곳에서만 선언
// AppDelegate.swift
func application(
    _ application: UIApplication,
    continue userActivity: NSUserActivity,
    restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
    guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
          let incomingURL = userActivity.webpageURL else { return false }

    handleLink(incomingURL)
    return true
}

// SceneDelegate.swift
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
    guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
        let incomingURL = userActivity.webpageURL else {
              return
    }

    handleLink(incomingURL)
}

확인하는 방법

  • wwww.<#Domain#>.com/.well-knwon/apple-app-site-association 웹서버 주소로 접근
  • https://app-site-association.cdn-apple.com/a/v1/<#Domain#> 주소로 접근
  • https://getuniversal.link/  링크로 접근해서 <#Domain#> 넣기
  • notes 앱에서 링크를 클릭하면 앱으로 이동
    • 카톡은 자체 브라우저로 링크를 이동하기 때문에 웹 주소로 이동
    • 주소창에 넣으면 “웹 서버로 이동”이라는 의사를 명확히 하는 것이기 때문에 안됨

배운점

  • 공식문서를 보고 학습하는 습관을 들여야겠다.
  • Deffered Universal Link가 있다는 것을 알았다.
    • Deferred Universal Links를 통해 사용자는 앱 설치 전후(로그인 상태 여부)에 동일한 링크를 통해 특정 콘텐츠로 유도
Comments