feat(ios): show notifications in foreground and add visual feedback
Implement UNUserNotificationCenterDelegate in AppDelegate to display notifications when app is in foreground. Add visual feedback indicator in test app UI to confirm notification delivery. Changes: - AppDelegate: Conform to UNUserNotificationCenterDelegate protocol - AppDelegate: Implement willPresent and didReceive delegate methods - AppDelegate: Set delegate at multiple lifecycle points to ensure it's always active (immediate, after Capacitor init, on app active) - UI: Add notification received indicator in status card - UI: Add periodic check for notification delivery (every 5 seconds) - UI: Add instructions on where to look for notification banner - Docs: Add IOS_LOGGING_GUIDE.md for debugging iOS logs This fixes the issue where scheduled notifications were not visible when the app was in the foreground. The delegate method now properly presents notifications with banner, sound, and badge options. Verified working: Logs show delegate method called successfully when notification fires, with proper presentation options set.
This commit is contained in:
@@ -3,9 +3,10 @@ import Capacitor
|
||||
import BackgroundTasks
|
||||
import DailyNotificationPlugin
|
||||
import ObjectiveC
|
||||
import UserNotifications
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
|
||||
|
||||
var window: UIWindow?
|
||||
|
||||
@@ -103,9 +104,64 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
// NOTE: Background task registration is handled by DailyNotificationPlugin.load()
|
||||
// Do NOT register here to avoid duplicate registration crash
|
||||
|
||||
// Set notification center delegate to show notifications in foreground
|
||||
// Set immediately and also after Capacitor initializes to ensure it's always set
|
||||
UNUserNotificationCenter.current().delegate = self
|
||||
NSLog("DNP-DEBUG: UNUserNotificationCenter delegate set to AppDelegate (immediate)")
|
||||
|
||||
// Also set after Capacitor initializes (in case it resets the delegate)
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
|
||||
UNUserNotificationCenter.current().delegate = self
|
||||
NSLog("DNP-DEBUG: UNUserNotificationCenter delegate re-set after Capacitor init")
|
||||
}
|
||||
|
||||
// Override point for customization after application launch.
|
||||
return true
|
||||
}
|
||||
|
||||
func applicationDidBecomeActive(_ application: UIApplication) {
|
||||
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||
|
||||
// Re-set delegate when app becomes active (in case Capacitor resets it)
|
||||
UNUserNotificationCenter.current().delegate = self
|
||||
NSLog("DNP-DEBUG: UNUserNotificationCenter delegate re-set in applicationDidBecomeActive")
|
||||
}
|
||||
|
||||
// MARK: - UNUserNotificationCenterDelegate
|
||||
|
||||
/**
|
||||
* Show notifications even when app is in foreground
|
||||
* This is required for test app to see notifications during testing
|
||||
*/
|
||||
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
|
||||
NSLog("DNP-DEBUG: ✅ userNotificationCenter willPresent called!")
|
||||
NSLog("DNP-DEBUG: Notification received in foreground: %@", notification.request.identifier)
|
||||
NSLog("DNP-DEBUG: Notification title: %@", notification.request.content.title)
|
||||
NSLog("DNP-DEBUG: Notification body: %@", notification.request.content.body)
|
||||
NSLog("DNP-DEBUG: Current delegate: %@", UNUserNotificationCenter.current().delegate != nil ? "SET" : "NOT SET")
|
||||
|
||||
// Show notification with banner, sound, and badge
|
||||
// Use .banner for iOS 14+, fallback to .alert for iOS 13
|
||||
if #available(iOS 14.0, *) {
|
||||
completionHandler([.banner, .sound, .badge])
|
||||
} else {
|
||||
completionHandler([.alert, .sound, .badge])
|
||||
}
|
||||
|
||||
NSLog("DNP-DEBUG: ✅ Completion handler called with presentation options")
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle notification tap/interaction
|
||||
*/
|
||||
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
|
||||
NSLog("DNP-DEBUG: Notification tapped: %@", response.notification.request.identifier)
|
||||
NSLog("DNP-DEBUG: Action identifier: %@", response.actionIdentifier)
|
||||
|
||||
// Handle notification tap if needed
|
||||
// For test app, we just log it
|
||||
completionHandler()
|
||||
}
|
||||
|
||||
func applicationWillResignActive(_ application: UIApplication) {
|
||||
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||
@@ -121,10 +177,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
|
||||
}
|
||||
|
||||
func applicationDidBecomeActive(_ application: UIApplication) {
|
||||
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||
}
|
||||
|
||||
func applicationWillTerminate(_ application: UIApplication) {
|
||||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user