Hi everyone,
I’m currently developing an app using Capacitor and I need to handle push notifications natively on iOS. Specifically, I want Capacitor to notify my AppDelegate with the contents of the push notification.
I’ve tried the following setup in my AppDelegate:
import UIKit
import Capacitor
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var pushNotificationHandler: CustomPushNotificationHandler?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize CustomPushNotificationHandler
self.pushNotificationHandler = CustomPushNotificationHandler()
// Configure NotificationRouter
notificationRouter.pushNotificationHandler = self.pushNotificationHandler
return true
}
}
Here is my CustomPushNotificationHandler:
import UIKit
import UserNotifications
import Capacitor
class CustomPushNotificationHandler: NSObject, NotificationHandlerProtocol {
func willPresent(notification: UNNotification) -> UNNotificationPresentationOptions {
// Additional tasks before the notification is presented
print("Notification received while app is in the foreground: \(notification.request.content.userInfo)")
return [.alert, .sound, .badge]
}
func didReceive(response: UNNotificationResponse) {
// Additional tasks when the user interacts with the notification
print("User interacted with the notification: \(response.notification.request.content.userInfo)")
NotificationCenter.default.post(name: Notification.Name("didReceiveRemoteNotification"), object: response.notification.request.content.userInfo)
}
}
Unfortunately, this doesn’t seem to be working. I need to obtain the push notification data natively in iOS.
my appdelegate
import UIKit
import Intents
import AVFAudio
import Capacitor
import Firebase
import PushKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var sip: SipMobile?
var callKit: CallKitIntegration?
var voipRegistry: PKPushRegistry?
var pushNotificationHandler: CustomPushNotificationHandler?
let notificationRouter = NotificationRouter()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
print("AppDelegate didFinishLaunchingWithOptions")
FirebaseApp.configure()
// Inicializar el manejador de notificaciones push personalizado
self.pushNotificationHandler = CustomPushNotificationHandler()
// Configurar el NotificationRouter
notificationRouter.pushNotificationHandler = self.pushNotificationHandler
self.sip = SipMobile()
self.callKit = CallKitIntegration(sip: self.sip!)
self.sip!.setVoip(callKit!)
self.voipRegistry = PKPushRegistry(queue: nil)
self.voipRegistry?.delegate = self.callKit
self.voipRegistry?.desiredPushTypes = [.voIP]
return true
}
@objc func handleWillPresentNotification(_ notification: Notification) {
if let notification = notification.object as? UNNotification {
let userInfo = notification.request.content.userInfo
print("Will present notification: \(userInfo)")
// Maneja la notificación aquí
}
}
@objc func handleDidReceiveNotificationResponse(_ notification: Notification) {
if let response = notification.object as? UNNotificationResponse {
let userInfo = response.notification.request.content.userInfo
print("Did receive notification response: \(userInfo)")
// Maneja la respuesta de la notificación aquí
}
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("AppDelegate didRegisterForRemoteNotificationsWithDeviceToken")
NotificationCenter.default.post(name: .capacitorDidRegisterForRemoteNotifications, object: deviceToken)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("AppDelegate didFailToRegisterForRemoteNotificationsWithError")
NotificationCenter.default.post(name: .capacitorDidFailToRegisterForRemoteNotifications, object: error)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// Manejar la notificación aquí
print("AppDelegate Notificación recibida: \(userInfo)")
NotificationCenter.default.post(name: Notification.Name("didReceiveRemoteNotification"), object: userInfo)
completionHandler(.newData)
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
return ApplicationDelegateProxy.shared.application(app, open: url, options: options)
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
}
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.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// 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:.
}
}
//extension AppDelegate: NotificationHandlerProtocol {
// func willPresent(notification: UNNotification) -> UNNotificationPresentationOptions {
// let userInfo = notification.request.content.userInfo
// print("AppDelegate NotificationHandlerProtocol Will present notification: \(userInfo)")
// // Maneja la notificación aquí
//
// return [.alert, .sound, .badge]
// }
//
// func didReceive(response: UNNotificationResponse) {
// let userInfo = response.notification.request.content.userInfo
// print("AppDelegate NotificationHandlerProtocol Did receive notification response: \(userInfo)")
// }
//
//
//}
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
print("AppDelegate UNUserNotificationCenterDelegate Notificación en primer plano: \(userInfo)")
NotificationCenter.default.post(name: Notification.Name("didReceiveRemoteNotification"), object: userInfo)
completionHandler([.alert, .sound, .badge])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
print("AppDelegate UNUserNotificationCenterDelegate Respuesta de notificación: \(userInfo)")
NotificationCenter.default.post(name: Notification.Name("didReceiveRemoteNotification"), object: userInfo)
completionHandler()
}
}
Could anyone guide me on how to properly set this up so that my AppDelegate can handle push notifications directly? Any help or examples would be greatly appreciated.
Thank you!