관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 4. DeepLink (딥 링크) - Dynamic Link (다이나믹 링크) 사용 방법 (Firebase, 공유하기 기능) 본문

iOS 응용 (swift)

[iOS - swift] 4. DeepLink (딥 링크) - Dynamic Link (다이나믹 링크) 사용 방법 (Firebase, 공유하기 기능)

jake-kim 2021. 10. 11. 03:46

1. DeepLink (딥 링크) - 앱 푸시, APNs (Apple Push Notification service ) 개념

2. DeepLink (딥 링크) - URL Scheme, URLComponents, Foreground, Background, Not Running 기초 개념

3. DeepLink (딥 링크) - FCM(Firebase Cloud Messaging) remote 푸시 사용 방법

4. DeepLink (딥 링크) - Dynamic Link (다이나믹 링크) 사용 방법 (Firebase, 공유하기 기능)

5. DeepLink ( 링크) - URL Scheme과 Dynamick Link를 이용한  링크 처리 방법

 

cf) Push Notification 처리 관련 메소드 총 정리 글은 이 포스팅 글 참고

 

* 딥링크 적용 사례

  • Push - 3번 방법
    • FCM과 같은 Server Provider 솔루션을 사용하여, 사용자에게 푸시를 발송하고 푸시를 탭한 경우 푸시 안의 URL을 분석하여 딥링크 처리
  • Dynamic Link - 4번 방법 (해당 글)
    • 앱에서 링크를 친구에게 공유하여 그 친구가 링크를 타고 들어가면 프로모션 혜택이 적용되거나 특정 화면 이동할 때 사용
    • 친구가 특정 앱 화면 링크 공유 > 해당 링크를 통해 설치를 한 후 실행 > "계속" 버튼 표출 > 친구가 공유했던 특정 페이지로 이동
    • 프로모션: 게임같은 경우 "추천인 코드를 입력해줘"가 아닌, 링크를 공유해주면 그 링크를 통해 앱을 설치했을때 자동으로 추천인 코드가 입력되는 기능
    • 특정 링크를 선택하여 앱 설치하면 혜택을 주는 기능 제공

Dynamic Link란?

접속한 플랫폼이 어디인가에 따라 적절한 반응을 하도록 하는 것

`다운로드 버튼`을 iOS에서 누르면 App Store로 이동하고, Android에서 누르면 Play Store로 이동

Dynamic Link 파라미터 예시

  • version 체크 > 버전 125번 이하이면 버전업데이트 페이지로 이동
  • 소셜 미디어 테그 > 친구에게 공유하는 링크를 만들 때, 링크에 대한 Title, Image, Description 설정 가능 (안하면 긴 URL만 표출)

Dyanamic Link 준비 - Firebase

  • Firebase 콘솔 접속 > Dynamic Links 탭 > 시작하기

  • URL 프리픽스는 `Google에서 제공하는 도메인`중에 하나 선택 > 계속
    • Google에서 도메인을 무료로 제공해주는 도메인 형식은 {YOUR_NAME}.page.link형식으로, 뒤에 .page.link만 붙이면 생성 가능

  • 완료

Dynamic Link 생성 - Firebase console 생성

  • 새 동적 링크 클릭

  • 딥 링크 URL 설정

  • 링크를 여는 데 사용할 앱 번들 ID를 "com.jake.sample.ExDeeplink"로 선언

  • 완성

생성 완료

  • '링크 세부정보'를 선택하여 입력사항 확인

  • 링크 미리보기(디버그)를 통해 전체적인 플로우 확인

  • 잘 생성되었는지 테스트
    • 아래 생성된 prefix 끝에 `/apple-app-site-association`를 붙인 URL로 이동되는 페이지 확인

  • 해당 컨텐츠 확인 - details가 비어있지 않다면 딥링크 준비 완료

Xcode 설정

  • dynamic link 활성화
    • Capability > Associated Domains 추가

  • applink기입 (YOUR_URL_PREFIX는 Firebase에 나와있는 prefix 중에서 `https://`를 제외한 도메인 값)
applinks:YOUR_URL_PREFIX

Dynamic Link 수신

  • SceneDelegate파일이 없고 AppDelegate만 존재하는 경우 설정 방법은 이곳 참고
  • SceneDelegate파일의 scene(_:continue:) 메소드에 dynamic link 수신 처리
import FirebaseDynamicLinks

    ...
    
    func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
        if let incomingURL = userActivity.webpageURL {
            let linkHandled = DynamicLinks.dynamicLinks().handleUniversalLink(incomingURL) { dynamicLinks, error in

                // Dynamic Link 처리
                print(dynamicLinks)
                // Optional(<FIRDynamicLink: 0x2808c94f0, url [https://exdeeplinkjake.page.link/navigation&ibi=com.jake.sample.ExDeeplink], match type: unique, minimumAppVersion: N/A, match message: (null)>)
            }
        }
    }
  • 앱이 not running 상태에서도 dynamic link를 통해 앱이 켜지는 경우에도 처리를 해주기 위해서 scene(_:willConnectTo:options:) 메소드에 처리
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let _ = (scene as? UIWindowScene) else { return }

        if let userActivity = connectionOptions.userActivities.first {
            self.scene(scene, continue: userActivity)
        }
    }
  • 위에서 Firebase Console에서 생성한 링크를 클릭하면 해당 앱으로 전환

dynamic link 생성 - swift에서 생성 방법

위 Firebase Console에서 딥링크를 구현했지만, iOS내부에서도 dynamic link를 동적으로 정의할때 사용

(iOS내부에서 설정하면 iOS플랫폼 독립적이므로 하나로 관리할 수 있는 Firebase Console 방법을 지향)

  • Swift Package Manager > FirebaseDynamicLinks 프레임워크 설치

  • AppDelegate에 FirebaseApp 초기화
import Firebase 
    
    ...
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        FirebaseApp.configure()
        return true
    }
  • FirebaseApp 초기화
import Firebase 
    
    ...
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        FirebaseApp.configure()
        return true
    }
  • iOS Builder API 사용
    • 번들 아이디가 com.jake.sample.ExDeeplink에서만 열리는 다이나믹 링크
    • 링크는 https://www.example.com/my-page로 설정
    • link 프로퍼티가 앱에 딥링크 url로 전달되고, bundle id와 일치하는 앱이 없다면 link에해당하는 web page 표출
import FirebaseDynamicLinks

    ...
    
    @IBAction func createDynamicLink(_ sender: Any) {

        // bundleID가 `com.jake.sample.ExDeeplink`에서만 열리는 `https://www.example.com/my-page` 링크 생성
        guard let link = URL(string: "https://www.example.com/my-page") else { return }
        let dynamicLinksDomainURIPrefix = "https://exdeeplinkjake.page.link"
        let bundleID = "com.jake.sample.ExDeeplink"
        let linkBuilder = DynamicLinkComponents(link: link, domainURIPrefix: dynamicLinksDomainURIPrefix)
        linkBuilder?.iOSParameters = DynamicLinkIOSParameters(bundleID: bundleID)
        linkBuilder?.androidParameters = DynamicLinkAndroidParameters(packageName: bundleID)

        guard let longDynamicLink = linkBuilder?.url else { return }
        print("The long URL is: \(longDynamicLink)")
        // https://exdeeplinkjake.page.link/?link=https%3A%2F%2Fwww%2Eexample%2Ecom%2Fmy%2Dpage&ibi=com%2Ejake%2Esample%2EExDeeplink&apn=com%2Ejake%2Esample%2EExDeeplink
    }
  • 짧은 Dynamic Link로 변환
    • linkBuilder() 사용 - 17자의 suffix로 생성
    • 해당 링크를 탭해도 long link와 동일하게 동작
        /// 짧은 Dynamic Link로 변환
        linkBuilder?.shorten(completion: { url, warnings, error in
            guard let url = url else { return }

            print("The short URL is: \(url)")
            // https://exdeeplinkjake.page.link/2B2YBe3jxNyJF19u6
        })
  • Parameter 삽입 방법
    @IBAction func createParameterDynamicLink(_ sender: Any) {
        guard let link = URL(string: "https://www.example.com/my-page") else { return }
        let dynamicLinksDomainURIPrefix = "https://exdeeplinkjake.page.link"
        let linkBuilder = DynamicLinkComponents(link: link, domainURIPrefix: dynamicLinksDomainURIPrefix)
        let bundleID = "com.jake.sample.ExDeeplink"

        linkBuilder?.iOSParameters = DynamicLinkIOSParameters(bundleID: bundleID)
        linkBuilder?.iOSParameters?.appStoreID = "123456789"
        linkBuilder?.iOSParameters?.minimumAppVersion = "1.2.3"

        linkBuilder?.androidParameters = DynamicLinkAndroidParameters(packageName: bundleID)
        linkBuilder?.androidParameters?.minimumVersion = 123

        linkBuilder?.analyticsParameters = DynamicLinkGoogleAnalyticsParameters(source: "orkut",
                                                                               medium: "social",
                                                                               campaign: "example-promo")

        linkBuilder?.iTunesConnectParameters = DynamicLinkItunesConnectAnalyticsParameters()
        linkBuilder?.iTunesConnectParameters?.providerToken = "123456"
        linkBuilder?.iTunesConnectParameters?.campaignToken = "example-promo"

        linkBuilder?.socialMetaTagParameters? = DynamicLinkSocialMetaTagParameters()
        linkBuilder?.socialMetaTagParameters?.title = "Example of a Dynamic Link"
        linkBuilder?.socialMetaTagParameters?.descriptionText = "This link works whether the app is installed or not!"
//        linkBuilder?.socialMetaTagParameters?.imageURL = URL(string: "https://www.example.com/my-image.jpg")

        guard let longDynamicLink = linkBuilder?.url else { return }
        print("The long URL is: \(longDynamicLink)")

        // https://exdeeplinkjake.page.link/?isi=123456789&utm_source=orkut&ibi=com%2Ejake%2Esample%2EExDeeplink&utm_campaign=example%2Dpromo&utm_medium=social&imv=1%2E2%2E3&link=https%3A%2F%2Fwww%2Eexample%2Ecom%2Fmy%2Dpage&pt=123456&ct=example%2Dpromo&apn=com%2Ejake%2Esample%2EExDeeplink&amv=123

    }

* 전체 소스 코드: https://github.com/JK0369/ExDeeplink

 

cf) dynamic link를 이용한 이메일 인증 로그인 방법: https://ios-development.tistory.com/768

 

* 참고

- dynamic link 생성: https://firebase.google.com/docs/dynamic-links/ios/create?hl=ko 

- dynamic link 수신: https://firebase.google.com/docs/dynamic-links/ios/receive?hl=ko 

- 동적 링크의 커스텀 도메인 설정: https://firebase.google.com/docs/dynamic-links/custom-domains?hl=ko

- Firebase DyanamicLinks: https://firebase.google.com/docs/dynamic-links/ios/create?hl=ko 

Comments