Reputation: 356
The thing is that notification service extension is useless by itself, except one thing that it can be shown when the app is killed. So with inapp notifications and content extension I can show custom notification, but that notification will appear only if the app is not killed/force-closed. Question: How to manage the inapp notifications in case there are content and service notifications extensions, and how to force notifications service extension to call/wake up the notification content extension.
Upvotes: 0
Views: 815
Reputation: 356
Seemed that I needed to clean the project and remove the app and install again. Here is the full steps for FCM to achieve this case, maybe some of the steps are redundant, but I don't want to touch it while it is working :
App is killed/closed: Notification appears with custom content view App is in background: Notification appears with custom content view App is in foreground: Notification arrives silently
From server side the notification should look like this
{ "notification"://mandatory { "data":{}, "body":""//seemed mandatory as well, anyway you can change it in service extension } "content_available":true,//mandatory "mutable_content":true,//mandatory "to":""//mandatory }
Create Notification Service Extension target.
In NotificationService in didReceive get the mutable content
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
Add your category to the content
bestAttemptContent.categoryIdentifier = "yourCategory"
After calling contentHandler(bestAttemptContent)
the standart notification appears.
Create Notification Content Extension target.
notification.request.content.userInfo["gcm.notification.data"]
. So in NotificationViewController fill the views with the data. Don't forget about the the preferredContentSize
.UNUserNotificationCenterDelegate
.In didFinishLaunchingWithOptions
add
UNUserNotificationCenter.current().delegate = self UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .alert, .sound]) { (granted, error) in } application.registerForRemoteNotifications()
In AppDelegate add
func application( _ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data ) { Messaging.messaging().apnsToken = deviceToken }
In userNotificationCenter willPresent check if your app is not running. I made it this way:
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { if self.window?.rootViewController == nil { completionHandler([.badge, .alert, .sound]) } UIApplication.shared.applicationIconBadgeNumber = UIApplication.shared.applicationIconBadgeNumber + 1 }
Handle the silent notification here:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void)
here you can get the custom data with the same way response.notification.request.content.userInfo["gcm.notification.data"]
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void)
Seems that's all :) . Ah, the extensions are working starting IOS 10. Please correct me if there is something missing or something is redundant.
Upvotes: 1