일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Xcode
- rxswift
- clean architecture
- SWIFT
- uitableview
- 클린 코드
- Protocol
- 애니메이션
- 리펙터링
- combine
- 리팩토링
- map
- 리펙토링
- MVVM
- Refactoring
- swift documentation
- tableView
- ribs
- uiscrollview
- Human interface guide
- collectionview
- UITextView
- UICollectionView
- Observable
- Clean Code
- 스위프트
- HIG
- RxCocoa
- swiftUI
- ios
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] 3. DeepLink (딥 링크) - FCM(Firebase Cloud Messaging) remote 푸시 사용 방법 본문
[iOS - swift] 3. DeepLink (딥 링크) - FCM(Firebase Cloud Messaging) remote 푸시 사용 방법
jake-kim 2021. 10. 8. 23:201. 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번 방법
- 앱에서 링크를 친구에게 공유하여 그 친구가 링크를 타고 들어가면 프로모션 혜택이 적용되거나 특정 화면 이동
FCM
- Firebase Cloud Messaging
- Provider Server가 FCM으로 설정되는 개념
Apple Developer에서 생성하는 .p8 형식의 키
- .p8 없이 Provider Server가 푸시를 보내려면 푸시 전용 certificate 인증서를 따로 만들어야하는 점이 존재
- .p8이 있다면 development버전과 ad-hoc 구분 없이 푸시를 받을 수 있는 편리함 존재
- .p8이 없이 Push 설정하려면 Apple Developer 사이트에서 App Identifiers에 Certificate를 따로 등록해야 가능
- 또 Certificates는 development와 Ad-hoc버전이 나누어져 있으므로 .p8키값 사용을 권장
FCM을 사용 준비
1) Apple Developer 사이트의 Apple 푸시 알림 인증 키 .p8 생성
- Apple 푸시 알림 인증키가 필요한 이유: FCM에서는 이 값을 이용하여 APNs에 인증값으로 송신
- Apple Developer > 계정 > Certificates, Identifiers & Profiles > Keys 탭
- Create a Key 혹은 Keys 옆에 있는 `+` 버튼 탭하면 아래 화면 등장 > Key name과 ENABLE 체크 후 Continue
- Register
- 아래 나와있는대로 다운로드 할 수 있는 파일이 있고 이 파일을 한번 다운받으면 다시 다운받지 못하므로, 잃어버리지 않게 보관 필요
- 다운로드를 누르면 .p8 형식의 푸시 인증서 키 확인
2) Apple Developer에 App Identifiers 생성
- 이미 App ID가 만들어져 있다면 이 단계는 패스
- 새로운 App Id 생성
- continue
- continue
- Description과 Bundle ID를 입력한 후에 스크롤하여 아래로 내려간 후 Push Notifications 체크 활성화 필요
- Push Notification 체크 후 Continue
- 생성된 것을 확인
3) Firebase에 프로젝트 등록
- firebase console > 프로젝트 추가(이미 프로젝트가 있다면 그 안에다가 새로운 앱 등록 가능)
- Firebase에서는 프로젝트 갯수에 제한이 있기 때문에 프로젝트 안에 여러 앱 등록 방법을 추천
- 프로젝트 > + 클릭 > iOS 클릭
- 앱 추가 > GoogleService-info.plist 다운로드
- Xcode에 GoogleService-info.plist 추가
- Firebase를 Xcode에 연동
- swift package manager에서 아래 검색 후 설치
https://github.com/firebase/firebase-ios-sdk.git
- FirebaseMessaging 체크 후 Add Package
- App Delegate에서 Firebase 초기화
4) Xcode에서 Push Notification 기능 활성화
5) device token 등록
- device token와 Server provider 개념은 앱이 푸시를 받는 원리 참고
- launchOptions에서 device token 요청
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
registerRemoteNotification()
return true
}
private func registerRemoteNotification() {
let center = UNUserNotificationCenter.current()
center.delegate = self
let options: UNAuthorizationOptions = [.alert, .sound, .badge]
center.requestAuthorization(options: options) { granted, _ in
// 1. APNs에 device token 등록 요청
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
- device token을 APNs에서 받으면 Firebase에 device token 등록
// 2. APNs에서 `device token 등록 요청`에 관한 응답이 온 경우, Provider Server인 Firebase에 등록
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
}
- 딥링크 url을 받을 델리게이트 구현
- SceneDelegate파일이 있다면, SceneDelegate의 scene(_:openURLContexts:)에서 url 수신
- SceneDelegate가 없다면, AppDelegate의 application(_:open:options:) -> Bool에서 url 수신
- 단, Firebase dynamic link를 사용한다면 AppDelegate의 userNotification(_:didReceive:)에서만 수신되므로 이곳에서 구현하는 것을 지향
- 예제에서는 SceneDelegate가 있다고하고 scene(_:openURLContexts:)에서 url수신
- Provider Server (Firebase)에서 딥링크로 아래에서 설정할 key값은 url, value값은 아래처럼 설정할 것으로 기억
- AppDelegate에 위 링크를 파싱하는 코드 추가
// my-app://navigation?name=jake
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async {
let userInfo = response.notification.request.content.userInfo
print(userInfo)
print(userInfo["url"] as? String)
guard let deepLinkUrl = userInfo["url"] as? String,
let url = URL(string: deepLinkUrl) else { return }
// 해당 host를 가지고 있는지 확인
guard url.host == "navigation" else { return }
// 원하는 query parameter가 있는지 확인
let urlString = url.absoluteString
guard urlString.contains("name") else { return }
// URL을 URLComponent로 만들어서 parameter값 가져오기 쉽게 접근
let components = URLComponents(string: urlString)
// URLQueryItem 형식은 [name: value] 쌍으로 되어있으서 Dctionary로 변형
let urlQueryItems = components?.queryItems ?? []
var dictionaryData = [String: String]()
urlQueryItems.forEach { dictionaryData[$0.name] = $0.value }
guard let name = dictionaryData["name"] else { return }
print("네임 = \(name)")
}
6) Provider Server인 Firebase에 1)번 단계에서 발급한 .p8파일 업로드
- 앱 설정 클릭 (프로젝트 설정)
- 클라우드 메시징 클릭
- 1)번에서 발급한 push 키 .p8 업로드, 키 ID와 팀 ID입력
- 키 ID는 발급한 곳에 존재 (Certificates, Identifiers & Profiles > Keys > 아까 만든 key 클릭하면 확인 가능)
- 팀 ID는 Apple Developer > 계정 > Membership에 존재
7) Provider Server인 Firebase에서 앱으로 푸시 전송
- iOS에서 앱이 푸시를 받는 원리: Provider Server에서 푸시 전송 요청 > APNs에서 수신 > APNs에서 auth 인증, key 인증 후 Provider Server와 앱에 전송
- Firebase 콘솔 > 설정 > 클라우드 메시징 탭 > Send Your first message 클릭
- 푸시 메시지 내용 입력
- Push에 딥링크 url정보 넣는 방법
- 콘솔 > 추가 옵션 부분에서 맞춤 데이터에 key-value쌍으로 삽입하면 완료
- 주의: 입력할 때 ""와 같은 큰따옴표를 입력하면 파싱할 때 어려움이 있으므로 문자열이라도 큰 따옴표 없이 하는것 주의
- 항목에 대해서 입력해 나가고 `검토` 버튼을 누르면 캠페인이 자동으로 생성
- 캠패인: 푸시 내용에 대해서 세팅했던 값이 저장
- 푸시 확인
- 주의: simulator에서는 APNs에 device token요청을 하면 등록이 되지 않기 때문에 실물 device에서 사용해야 테스트 가능
- AppDelegate에서 딥링크 url 처리
- 사용자가 푸시를 탭한 경우 호출되는 델리게이트 userNotificationCenter(_:didReceive:) 메소드에서 url 확인
extension AppDelegate: UNUserNotificationCenterDelegate {
...
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async {
print(response.notification.request.content.userInfo)
}
}
- "url"부분을 파싱하여 딥링크 처리
// 결과
[AnyHashable("aps"): {
alert = {
body = "\Uc54c\Ub9bc \Ud14d\Uc2a4\Ud2b8";
title = "\Ud478\Uc2dc \Uba54\Uc2dc\Uc9c0 \Ud14c\Uc2a4\Ud2b8 \Uc81c\Ubaa9";
};
badge = 1;
"mutable-content" = 1;
},
AnyHashable("google.c.fid"): eNqS247ay00TlrnaEbt0CG,
AnyHashable("google.c.a.e"): 1,
AnyHashable("url"): "my-app://navigation?name=jake",
AnyHashable("google.c.a.c_id"): 8913753677916977018,
AnyHashable("google.c.a.udt"): 0,
AnyHashable("gcm.message_id"): 1633859324973797,
AnyHashable("google.c.a.ts"): 1633859324,
AnyHashable("gcm.n.e"): 1,
AnyHashable("google.c.a.c_l"): 푸시 메시지 테스트 제목,
AnyHashable("google.c.sender.id"): 1018046236453]
Cloud Messaging에서 `테스트 메시지 전송` 사용 방법
- 테스트 메시지 전송 클릭
- `FCM 등록 토큰 추가`화면에서 필요한 FCM 등록 토큰을 구하는게 필요
- App Delegate에서 `Messageing.messaging().token {...}`을 추가한 다음에 token값을 출력 후 위에다 복붙하면 완료
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
registerRemoteNotification()
Messaging.messaging().token { token, error in
print("토큰 = \(token)") <-- 여기
}
return true
}
* 전체 소스 코드: https://github.com/JK0369/ExDeeplink
* 참고
- Firebase: https://firebase.google.com/docs/cloud-messaging/ios/client?hl=ko
- Firebase with Swift Package Manager: https://firebase.google.com/docs/ios/swift-package-manager