您错过了delegate
,并且告诉UNUserNotificationCenter
如何在前台显示通知.
extension NotificationManager: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification) async -> UNNotificationPresentationOptions {
.banner
}
}
其余的manager
个看起来像.
@Observable final class NotificationManager: NSObject {
private(set) var isPermissionGranted = false
let userNC = UNUserNotificationCenter.current()
override init() {
super.init()
userNC.delegate = self
}
func sendNotifications() async throws {
let id = UUID().uuidString
let content = UNMutableNotificationContent()
content.title = "Let's feed the cat"
content.subtitle = "It looks hungry"
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 60, repeats: true)
let request = UNNotificationRequest(identifier: id,content: content,trigger: trigger)
try await userNC.add(request)
print("\(#function) :: scheduled")
}
func requestAuthorization () async throws {
do {
isPermissionGranted = try await userNC.requestAuthorization(options: [.alert, .badge, .sound])
} catch {
print(error)
}
}
func cancelAll() {
userNC.removeAllPendingNotificationRequests()
}
}
请注意,您应该在应用程序的最顶端使用创建manager
@State private var manager: NotificationManager = .init()
并将其注入应用程序,
.environment(manager)
所以你可以在任何地方访问它,
@Environment(NotificationManager.self) private var manager
重要的是,delegate
是稳定的,这样应用程序就不会错过通知.
这是View
个样品
import SwiftUI
import RealityKit
import UserNotifications
struct NotificationSample: View {
@Environment(NotificationManager.self) private var manager
@State private var date: Date?
@State private var isScheduling: Bool = false
var body: some View {
RealityView { content, attchments in
guard let attachment = attchments.entity(for: "Feed") else {return}
content.add(attachment)
} update: { content, attchments in
} attachments: {
Attachment(id: "Feed") {
VStack {
if let date {
Text(date, style: .timer)
}
Button("FEED THE CAT") {
isScheduling.toggle()
}.task(id: isScheduling) {
guard isScheduling else {return}
do {
try await manager.sendNotifications()
} catch {
print(error)
}
isScheduling = false
date = Calendar.current.date(byAdding: .minute, value: 1, to: Date())
}.disabled(!manager.isPermissionGranted)
}
}
}
.task {
do {
try await manager.requestAuthorization()
} catch {
print(error)
}
manager.cancelAll()
}
}
}