-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAppDelegate.swift
More file actions
154 lines (122 loc) · 4.42 KB
/
AppDelegate.swift
File metadata and controls
154 lines (122 loc) · 4.42 KB
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//
// AppDelegate.swift
// Codive
//
// Created by Claude on 4/26/26.
//
import UIKit
import FirebaseMessaging
import UserNotifications
final class AppDelegate: NSObject, UIApplicationDelegate {
/// 앱이 죽어있을 때 푸시 탭으로 실행된 경우 저장해두는 pending 데이터
static var pendingPushUserInfo: [AnyHashable: Any]?
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
UNUserNotificationCenter.current().delegate = self
Messaging.messaging().delegate = self
requestNotificationPermission(application)
return true
}
// MARK: - APNs Token
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
Messaging.messaging().apnsToken = deviceToken
}
func application(
_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error
) {
#if DEBUG
print("[Push] APNs 등록 실패: \(error.localizedDescription)")
#endif
}
// MARK: - Permission
private func requestNotificationPermission(_ application: UIApplication) {
let options: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(options: options) { granted, error in
#if DEBUG
if let error {
print("[Push] 권한 요청 실패: \(error.localizedDescription)")
} else {
print("[Push] 알림 권한 허용: \(granted)")
}
#endif
guard granted else { return }
DispatchQueue.main.async {
application.registerForRemoteNotifications()
}
}
}
}
// MARK: - UNUserNotificationCenterDelegate
extension AppDelegate: UNUserNotificationCenterDelegate {
// 포그라운드에서 알림 수신 시 배너 표시
func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
) {
completionHandler([.banner, .badge, .sound])
}
// 알림 탭 시 처리
func userNotificationCenter(
_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void
) {
let userInfo = response.notification.request.content.userInfo
#if DEBUG
print("[Push] 알림 탭 userInfo: \(userInfo)")
#endif
// MainTabView가 아직 없으면 pending으로 저장, 있으면 바로 전달
AppDelegate.pendingPushUserInfo = userInfo
NotificationCenter.default.post(
name: .pushNotificationTapped,
object: nil,
userInfo: userInfo
)
completionHandler()
}
}
// MARK: - MessagingDelegate
extension AppDelegate: MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
guard let fcmToken else { return }
#if DEBUG
AppLog.push.debug("FCM 토큰: \(fcmToken.masked(), privacy: .public)")
#endif
// UserDefaults에 저장 (로그인 후 서버 전송용)
UserDefaults.standard.set(fcmToken, forKey: "fcmToken")
// 로그인 상태면 서버에 즉시 전송
Task {
await sendFCMTokenToServerIfNeeded(fcmToken)
}
}
@MainActor
private func sendFCMTokenToServerIfNeeded(_ fcmToken: String) async {
let tokenService = TokenService()
guard tokenService.hasValidTokens(),
!tokenService.isAccessTokenExpired() else {
return
}
do {
let authAPIService = AuthAPIService()
try await authAPIService.renewDeviceToken(deviceToken: fcmToken)
#if DEBUG
print("[Push] 서버에 FCM 토큰 전송 완료")
#endif
} catch {
#if DEBUG
print("[Push] 서버 FCM 토큰 전송 실패: \(error.localizedDescription)")
#endif
}
}
}
// MARK: - Notification Name
extension Notification.Name {
static let pushNotificationTapped = Notification.Name("pushNotificationTapped")
}