Files
mayday/Mayday/Services/PushNotificationService.swift
T

66 lines
2.2 KiB
Swift

import Foundation
import UserNotifications
import UIKit
@MainActor
final class PushNotificationService: NSObject, UNUserNotificationCenterDelegate {
static let shared = PushNotificationService()
override private init() {
super.init()
UNUserNotificationCenter.current().delegate = self
}
func requestPermission() async -> Bool {
do {
let granted = try await UNUserNotificationCenter.current()
.requestAuthorization(options: [.alert, .badge, .sound])
return granted
} catch {
return false
}
}
func registerForRemoteNotifications() {
UIApplication.shared.registerForRemoteNotifications()
}
func handleDeviceToken(_ tokenData: Data) {
let token = DeviceTokenFormatter.hex(tokenData)
Task {
try? await HTTPClient.shared.request(.registerDevice(token: token, platform: DevicePlatform.ios)) as DeviceToken
}
}
func handleRemoteNotification(_ userInfo: [AnyHashable: Any]) async {
guard let aps = userInfo["aps"] as? [String: Any] else { return }
if let badge = aps["badge"] as? Int {
try? await UNUserNotificationCenter.current().setBadgeCount(badge)
}
// Live Activity start/update/end pushes (apns-push-type: liveactivity)
// are handled entirely by the OS via Push-to-Start tokens and per-activity
// pushTokens they never land in this delegate. Only regular alert/badge/sound
// pushes reach here, and the only thing we owe them is the badge update above.
}
// MARK: - UNUserNotificationCenterDelegate
nonisolated func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
) {
completionHandler([.banner, .badge, .sound])
}
nonisolated func userNotificationCenter(
_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void
) {
completionHandler()
}
}