일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 리팩토링
- HIG
- Protocol
- 스위프트
- collectionview
- 리펙터링
- uitableview
- swiftUI
- ribs
- Refactoring
- Xcode
- 애니메이션
- Observable
- uiscrollview
- RxCocoa
- swift documentation
- UICollectionView
- Human interface guide
- rxswift
- map
- ios
- SWIFT
- clean architecture
- 리펙토링
- tableView
- 클린 코드
- UITextView
- Clean Code
- MVVM
- combine
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] 4. DeepLink (딥 링크) - Dynamic Link (다이나믹 링크) 사용 방법 (Firebase, 공유하기 기능) 본문
[iOS - swift] 4. DeepLink (딥 링크) - Dynamic Link (다이나믹 링크) 사용 방법 (Firebase, 공유하기 기능)
jake-kim 2021. 10. 11. 03:461. 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 설정
- dynamic link pamameter 형식 종류 참고: 파라미터 문자열이 미리 정해져 있고, 이 값을 채워서 사용
- 링크를 여는 데 사용할 앱 번들 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