Hellojeffy Hellojeffy - 10 months ago 77
Swift Question

Do not display a remote notification based on custom data

I would like to give users the option to enable/disable certain types of notifications. For example, turn on push notifications for private messages, but turn off for public posts. I was wondering if it was possible to do this on the client side after receiving the APN (in didReceiveRemoteNotification), I wasn't sure if the notification is already displayed before didReceiveRemoteNotification is called.

Currently I am using OneSignal to send push notifications, and am sending them with content-available true (1). This correctly triggers didReceiveRemoteNotification while the app is in the background. Based on the data I sent, I want to show or not show any banner push notification at all.

Here is what I have attempted so far, I'm able to get the data I need but I haven't been able to figure out how to tell the iDevice to not display it at all:

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print("****this happened****")
if let customData = userInfo["custom"] as? [String: Any] {
if let additionalData = customData["a"] as? [String: Any] {
if let notificationType = additionalData["notification_type"] as? String {
if notificationType == "follow" {
print("do not want to display")
if var apsData = userInfo["aps"] as? [String: Any] {
apsData.removeValue(forKey: "content-available")
} else {
print("dispaying this notification")

The other way I have thought about it is to store the notifications settings for users into my database, and when a user is sending a push notification to check against those to see whether or not they should even send a push. I would just like to see if it is possible to tackle this without adding more database querying.

EDIT: I also use OneSignal.initWithLaunchOptions and noticed that this gets called before didReceiveRemoteNotification in handleNotificationReceived, I am wondering if it is possible to stop the push notification here

if receivedNotification?.payload != nil {
if receivedNotification?.payload.additionalData != nil {
if let data = receivedNotification?.payload.additionalData["notification_type"] as? String {
if data == "follow" {
print("do not display this")

Answer Source

Instead I recommend filtering on your server as sending a notification to all devices (just to omit them from being displayed) has down sides including; extra battery drain and content-available notifications do not work when the user swipes away the app.

You can use mutable-content instead which will fire your UNNotificationServiceExtension but this only works on iOS 10 and you still need to take battery into consideration.

You can get the device's OneSignal player id by calling IdsAvailable where you can store this on your back end. Then you can then use include_player_ids on the create notification REST API call to target only the users who should receive the notification.