How to group notifications like whatsapp on IOS - ios

I have in my app some notifications that you recive with GCM but every notification show in one target so when you get 2 or 3 notifications it makes annoying.
How to group all notifications in one target for my app? I think that will be like android, i have to identify the notification with some ID but i did not find any information about it.
Thats the code that execute when the app is in background:
// [START ack_message_reception]
func application( application: UIApplication,
didReceiveRemoteNotification userInfo: [NSObject :AnyObject]) {
print("Notification received: \(userInfo)")
// This works only if the app started the GCM service
GCMService.sharedInstance().appDidReceiveMessage(userInfo);
// Handle the received message
// [START_EXCLUDE]
NSNotificationCenter.defaultCenter().postNotificationName(messageKey, object: nil,
userInfo: userInfo)
// [END_EXCLUDE]
}
And the GCM message code is:
array( 'body' => 'Someone wants to practice with you !!!',
"sound" => "default",
"vibrate" => "1",
"time_to_live" => "1"
);
Thank you for your help.

I know this question was asked long ago but I am posting this answer it might help someone looking for the same solution. It is possible to group notifications at client side from iOS 12.
What you need to do is just to set one property and it will do all for you. Below is the explanation with example to do that.
UNMutableNotificationContent *content;
// Set all the properties like title, body etc. Here I am just going to explain how you can group notifications.
// Set property to group notifications
content.threadIdentifier = #"your group identifier";
Explanation: We have a property named threadIdentifier to group notifications, you just need to set this identifier to different unique group identifiers and iOS will handle the rest. It will show all the notifications having same identifier as one group.
Example: If we consider WhatsApp example they group messages notifications based on message sender, so we can set message sender number/identifier as threadIdentifier that's it.
content.threadIdentifier = #"messageSenderNumber"
Here is reference to Apple's guide for Using Grouped Notifications

Multiple notifications with the same collapse identifier are displayed to the user as a single notification. This can be handled from server side not at client side. APNS header apns-collapse-id will be used to update previously sent notification.
Refer to this for further description:
Table 8-2APNs request headers
Apple Developer Guide

Related

Removing Remote Notifications From Notification Center

I have a requirement to aggregate remote notifications of the same type.
example:
if a user received a push notification saying:"user 1 commented on your post", and then received "user 2 commented on your post", when receiving the second push I should remove the first notification and create a custom notification saying "2 users have commented on your post".
I'm getting the counter in the userInfo dictionary and I'm using NotificationService Extension in order to modify the notification's content.
the problem is I'm presenting 2 notifications:
"user 1 commented on your post"
"user 3 and 2 others have commented on your post"
instead of only the 2nd notification.
I've tried initializing UNNotificationRequest with custom identifier but still I'm getting double notifications (the original one and then the custom one).
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: ["push.comment"])
if let username = bestAttemptContent.userInfo["sender"] as? String,
let count = bestAttemptContent.userInfo["views_counter"] as? Int {
bestAttemptContent.title = "\(username) and \(count) others have commented on your post"
}
bestAttemptContent.body = "tap to see"
let request = UNNotificationRequest(identifier: "push.comment", content: bestAttemptContent, trigger: nil)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
I tried using available-content : 1 in the notification's payload, but I'm not able to modify the notification when the app is terminated (not in background/foreground).
Basically I want a similar behaviour to facebook's messenger app.
Any Suggestions?
Push Notifications grouping is a feature that is provided in Android applications, but it is impossible to achieve the same on iOS. Because it should be handled by operation system(in other case it will be not possible to achieve when app is closed or minimized) and iOS doesn't provide this support.
So I read in Apple's documentation that when setting content-available : 1 in the aps object it launches the app in a background mode and its possible to handle the received silent push.
its important to avoid setting the mutable-content : 1 and add background modes with remote notifications on in the apps configurations.

Push notification works only when app launched with Xcode

I have a big problem, I set up (with great difficulty) push notifications on my iOS project. I decided to receive the data of the notification in the "didReceiveRemoteNotification" method of the "AppDelegate" then to create it programmatically (in order to carry out mandatory personal treatment). Everything works perfectly, only when I launch my application without the help of Xcode, I no longer receive the notifications, the notification creation code is not executed. I do not know what to do ...
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: #escaping
(UIBackgroundFetchResult) -> Void) {
let body = userInfo["body"]
print(userInfo)
if #available(iOS 10.0, *) {
let content = UNMutableNotificationContent()
content.body = body! as! String
let trigger = UNTimeIntervalNotificationTrigger(timeInterval:
1, repeats: false)
let request = UNNotificationRequest(identifier: "idt", content:
content, trigger: trigger)
UNUserNotificationCenter.current().add(request,
withCompletionHandler: nil)
} else {
// Fallback on earlier versions
}
completionHandler(UIBackgroundFetchResult.newData)
}
Thanks you very much
When you launch your app from a notification you need to check the launchOptions in application:didFinishLaunchingWithOptions: to see if UIApplicationLaunchOptionsRemoteNotificationKey is present.
According to the Documentation:
The value of this key is an NSDictionary containing the payload of the remote notification. See the description of application:didReceiveRemoteNotification: for further information about handling remote notifications.
This key is also used to access the same value in the userInfo dictionary of the notification named UIApplicationDidFinishLaunchingNotification.
Once you determine that the launch contains a notification, invoke your notification handler method with the notification payload obtained from launchOptions.
What you have now, which is application(_:didReceiveRemoteNotification:) is only triggered when the app is already running:
If the app is running, the app calls this method to process incoming remote notifications. The userInfo dictionary contains the aps key whose value is another dictionary with the remaining notification
You need to check in your project settings/Capabilities - Background Modes - Remote notifications
Enable Remote notifications in Capabilities.
{
"aps" : {
"content-available" : 1,
"badge" : 0,
"Priority" : 10
},
"acme1" : "bar",
"acme2" : 42
}
The notification’s priority:
10 The push message is sent immediately.
The remote notification must trigger an alert, sound, or badge on the device. It is an error to use this priority for a push that contains only the content-available key.
https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/BinaryProviderAPI.html#//apple_ref/doc/uid/TP40008194-CH13-SW1
When the device is running and connected to Xcode, the system treats silent notifications as high-priority simply because the OS is smart enough to know "You must be debugging your app, so I will treat your app's tasks as high priority".
When the device is disconnected from Xcode, the system then treats silent notifications as low-priority. Therefore, it doesn't guarantee their delivery in order to improve battery life.

badge should be set before opening the app in IOS

When notification received on IOS device at that time the badge should be changed and Badge should be set before opening the app.
I check this onNotificationOpen() method. But when I tap on notification then it calls.
I use cordova-plugin-firebase.
Here is the link https://github.com/arnesson/cordova-plugin-firebase
But is there a method that calls when the notification received on IOS device?
$ionicPlatform.ready(function() {
if (typeof FirebasePlugin != 'undefined') {
window.FirebasePlugin.subscribe("notficationsubscribe");
// Below method calls when i tap on notifcation and sets the badge number
window.FirebasePlugin.onNotificationOpen(function(data) {
window.FirebasePlugin.setBadgeNumber(4);
}
}
}
Above FirebasePlugin.onNotificationOpen() method calls when I tap on notification and sets the badge number, but I want to set the badge when notification received.
Anyone have ideas? How can I achieve it?
Actually i set a logic for it.
1) I stored a badgeCounter value to database.
2) when i wants to send the notification at that time i retrieve it from database
var badge = badgeCounter // it is an integer value
var notification = {
'title': 'Stock available',
'body': 'Click here to more details...',
'sound': 'default',
'badge': badge
};
3) After tap or click on notification, i cleared the badge using below.
window.FirebasePlugin.setBadgeNumber(0);
4) And also in database i update the value to '0' (zero).
Thus, i solve it and it perfectly works for me.
You don't set this with code, it will set itself based on what your notification contains. You'll have to include "badge":1 (or whatever number) in the notification payload when you send it from your server (Firebase). I'm not sure how it works with firebase, but take a look at the documentation for remote notifications. Notice the "Badge"-key.

iOS push notification not received when screen is locked

I am using parse for push notification. Once I receive remote notification I pass it to the local notification, but issue is when screen is locked didReceiveRemoteNotification does not hit. I don't receive any notification.
I am using iOS8
Here's my payload:
{
CommentId = "8082a532-2380-4af5-bb3f-d247cfca519b";
CommentTitle = test; action = "com.lelafe.one4communities.Notifications.NotificationActivity";
aps = { };
moduleIdentifier = 8;
nTitle = "Comment posted by someone";
postingID = "c57a3d27-cfe5-41e9-a311-98a9fd7749ad";
}
There is one more parameter that you need to pass to your payload i.e. content-available and set its value to 1. It needs to be passed in case we wish that our app should receive notifications in the background.
The official documentation of parse describes this parameter as follows:
+content-available: (iOS only) If you are a writing a Newsstand app, or an app using the Remote Notification Background Mode introduced in iOS7 (a.k.a. "Background Push"), set this value to 1 to trigger a background download.
The problem is your dictionary aps:
Try checking out Apple's Documentation about The Notification Payload
Also Quoting #mamills answer:
If there is no badge, no alert, and no sound specified in the
dictionary (for the "aps" key) then a default message will not appear
and it will be completely silent.
Look again at example 5 in the document you referenced. aps can be
empty, and you can specify whatever custom data you would like as they
do with the "acme2" key. The "acme2" data is an example of where your
server's "special" payload could reside within the JSON payload.

is it possible to send a push notification without using the alert attribute in a json using iOS?

I am trying to send a json format which doesn't have an "alert" attribute. The thing is, when I try to remove the alert attribute, the notification won't appear. Is there any way I can handle this? Thanks in advance
P.S I've tried to use action, however it still doesn't show up (I think this is only possible in android)
Yes, you can do it. It is possible to send a push notification without an alert. You can even register your application just to badge notifications, in which case the provider server won't even be able to send alerts or sounds.
The Notification Payload
Each push notification carries with it a payload. The payload specifies how users are to be alerted to the data waiting to be downloaded to the client application. The maximum size allowed for a notification payload is 256 bytes; Apple Push Notification Service refuses any notification that exceeds this limit. Remember that delivery of notifications is “best effort” and is not guaranteed.
For each notification, providers must compose a JSON dictionary object that strictly adheres to RFC 4627. This dictionary must contain another dictionary identified by the key aps. The aps dictionary contains one or more properties that specify the following actions:
An alert message to display to the user
A number to badge the application icon with
A sound to play
Note that it says one or more of the properties. The alert property is optional. You can even send a notification with an empty aps dictionary (i.e. send only custom properties).
The following example shows an empty aps dictionary; because the badge property is missing, any current badge number shown on the application icon is removed. The acme2 custom property is an array of two integers.
{
"aps" : {
},
"acme2" : [ 5, 8 ]
}
The only alert the user will see it the alert that asks him/her whether to allow push notifications. That alert will only be displayed the first time the app is launched after installation.
In the below example you register to non alert notifications (badges and sounds only) :
Registering for remote notifications
- (void)applicationDidFinishLaunching:(UIApplication *)app {
// other setup tasks here....
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
}
// Delegation methods
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
const void *devTokenBytes = [devToken bytes];
self.registered = YES;
[self sendProviderDeviceToken:devTokenBytes]; // custom method
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSLog(#"Error in registration. Error: %#", err);
}
Hope this will help you.

Resources