For getting familiar with iOS User Notification I made a trial-app.
Here's the source-code:
import SwiftUI
import UserNotifications
struct ContentView: View {
var body: some View {
VStack(spacing: 30) {
Button("Schedule User Notification") {
Task {
let center = UNUserNotificationCenter.current()
do {
let answer = try await center.requestAuthorization(options: [.alert, .badge])
switch answer {
case true:
scheduleNotification()
print("Called: scheduleNotification")
case false:
print("Permission Denied")
try await center.requestAuthorization(options: [.alert, .badge])
}
} catch {
print(error)
}
}
}.buttonStyle(.borderedProminent)
}
.padding()
}
func scheduleNotification() {
let content = UNMutableNotificationContent()
content.title = "Title [\(Date.now.formatted(date: .abbreviated, time: .shortened))]"
content.subtitle = "Notification-Subtitle"
content.body = "Notification-Body"
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 10, repeats: false)
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request)
{ error in
if let error = error {
print(error.localizedDescription)
} else {
print("Notification scheduled")
}
}
}
}
Generally, the shown code works.
But it isn't clear to me, in which state the device has to be, that the notification appears.
When the app is in the foreground, the notification doesn't appear. I have got it appearing, when I press the schedule-notification button, then lock the screen, wait for 10 seconds, then press home-button of the emulator.
What are the prerequisite for user-notifications to appear?
Becomes a scheduled notification discarded, when the timerInterval runs out and the app is in the foreground? Is it then gone or does it become kept somehow, for appearing later?
@main
struct YourApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
AppDelagate
// AppDelegate.swift
class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
UNUserNotificationCenter.current().delegate = self
return true
}
}
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
// Here we actually handle the notification
print("Notification received with identifier \(notification.request.identifier)")
// So we call the completionHandler telling that the notification should display a banner and play the notification sound - this will happen while the app is in foreground
completionHandler([.banner, .sound])
}
}