Setup: I have successfully deployed a push notification system on my server! That being said, I am able to send notifications to my iOS devices which can send alert messages when something happens on the webserver, for example: when a new customer is added to the system.
This displays a nice message like so
You have a new customer. More money baby!
And the notification is of course silent when my application is open but simply automatically updates the customers table for me so I don't have to manually keep refreshing my table.
Problem: Since then the system has scaled up and now I'm getting messages like that to my device all the time at least a few every hour, this bothers me.
My proposed solution is to only update my table every single time a new user is added so this would require a push notification to be sent for every new user that is created, thats perfect, but for it to not display messages on my notification center like it did before.
Question: Is there a way to silently send push notification so that I don't get any messages like that on my device, but when the application is running for the push notification to still pop through so that I can update the UI without having to manually refresh my customer's table?
Is it just a case of leaving blank body parameter of the json push notification sent from my server?
What I don't want: I don't want to resolve to having to hide the notification from my own application :')
You could use the silent push notifications of iOS 7+.
If into the payload that you send from your server you add the key "content-available" with value 1 and remove the key "alert", you will get the push but with out get the message on your screen.
When you receive this kind of push you will have 30 seconds of execution time*, time that could be enough to refresh your user table and next time you open the app you will have up to date the table data.
The system will wake up your app and call the method
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler
on the AppDelegate.m
The format payload should be that:
{"aps":{"content-available":1}}
also you could add more fields if you want like badge or extra dictionary data to use it, are optionals.
{"aps":{"content-available":1, "sound":"", "badge":1}}
If for some reason you are not getting the push try adding "sound": "", seems like could be a bug around the silent push.
*Don't forget that execution time due to silent push won't happen if the you or the use swipe up the app and terminate it.
I hope this is useful for you! :)
According to the "Local and Push Notification Programming Guide", 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
So you could send a notification that contains a badge count only. The payload would
look just like
{
"aps" : {
"badge" : 9
}
}
here it the format
/*
aps =
{
Name = "";
alert = "Testing";
price = 0;
//sound = default;//do not send it from server
type = add;
};
*/
in swift get remote notification when app is open
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject])
{
if let aps = userInfo["aps"] as? NSDictionary {
var message = aps["alert"]
println("my messages : \(message)")
}
}
Related
I want to send all users of my app a Push Notification that will bring them to a certain page in the app.
However, I only want one user to be able to tap it and go to the page, and when one user loads the page that the push brings them into, I want to silently remove the push from all other users.
Is this possible to do? I'm not sure how to grab all sent push notifications, whereas the UNUserNotificationCenter only grabs pushes sent on that device.
Thank you in advance!
I believe that this is possible if you use silent notifications.
Send a silent notification of type A.
All devices receive a type A notification and create local notifications in their UI.
A user press this local notification and load the page from the server.
Application of that use on the click / load event will send some request/event to your server that someone access the link.
Your server will send another silent notification of type B.
All devices receive the type B notification and use the code of the links to discard the type A notification from their own notification center.
Here are relevant posts of clearing notifications:
all the notifications of your application:
iOS application: how to clear notifications?
a specific notification:
https://stackoverflow.com/a/6341476/944070
Possible problems / Issues:
Between the user's click step 3 and step 6 it may take some time if you consider the push delivery times, so someone else may press the link. It's not instant. This can become worse in bad network conditions.
It may be annoying to the users that get a beep on their devices and the notification at last cleared because someone else was faster.
You cannot remove a push notification once it has been sent.
Although you could update the App badging by sending another push to reset the badging to zero. While this won't remove the previous push message, it can hide the red badging on the App icon.
You can simply remove the notification by
Sending the badge count as 0
APNS payload will be :
{
"aps" : {
"alert" : "",
"badge" : 0,
"sound" : "bingbong.aiff"
}
}
If you want to remove or decrease badge count number then you can do it easily with
UIApplication.shared.applicationIconBadgeNumber = max(UIApplication.shared.applicationIconBadgeNumber - 1, 0)
If you want to remove a single notification from notification center then, you can do it by using UNUserNotificationCenter in iOS 10 and above.
UNUserNotificationCenter object manage all notification-related behaviors in app or app extension.
You can removes the specified notification requests from Notification Center by using :
func removeDeliveredNotifications(withIdentifiers: [String])
I have implement silent push notification.So "didReceiveRemoteNotification" method called when application is inactive state in ios 9.
There are some case when application is inactive state.
1.When user tab on particular notification.
2.When call or message receive.
3.When notification center and control center open.
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
if(application.applicationState == UIApplicationStateInactive) //Inactive state
{
[self RedirectScreenBasedOnNotification:self.userInfoDic];//Screen Redirection code
}
}
So how can i handle silent notification when app is inactive state?
I have face problem is when notification center open at that time if any notification come then redirection will do,but i want to stop that.
Notification payload:-
aps = {
alert = "Test Dev 5 startd following you ";
"content-available" = 1;
"link_url" = "https://raywenderlich.com";
message = {
friend = {
email = "abc#gmail.com";
name = "Test Dev 5";
photo = "";
"user_id" = 27;
};
id = 3;
"is_business_sent" = 0;
message = "Test Dev 5 startd following you ";
};
sound = default;
}
Thanks in advance
Silent push notifications do not trigger user interactions. When a silent notification payload includes keys for user interaction things go wrong - iOS can't reason about wether the intent is to present something to the user, or to keep the notification silent and handled without user interaction. Sometimes the silent notification may work, other times it may be presented like a normal notification with user interaction. It can be one or the other, not both.
If the silent push key content-available is present in the aps payload the keys alert, sound, or badge should not be.
You can use my Push Notification Payload Validation Tool to check the content of your notification. The payload you posted in your question has several problems - the aps key should only contain Apple keys defined in Generating Push Notifications. All of your custom keys and values should be outside the aps object.
application:didReceiveRemoteNotification:fetchCompletionHandler: will only be called for silent push notifications. If the notification payload contains both content-available and one or more of alert, sound, or badge iOS will not know which method to call and you may see inconsistent behavior.
If you are just trying to show a non-silent notification you do not need to implement application:didReceiveRemoteNotification:fetchCompletionHandler:. Instead implement application:didReceiveRemoteNotification: for iOS 9 and userNotificationCenter:willPresentNotification:withCompletionHandler: for iOS 10 and later.
As far as silent notifications and the inactive application state, there is nothing special to be done here. Silent notifications are intended to 'hint' to the application that it should refresh content. When a silent notification is received the application is required to process the content update within 30 seconds and then call the fetch completion handler. When iOS executes the fetch completion handler it take a new restoration snapshot of the updated UI. This happens even when the application is inactive.
You can add your code in this If condition.
if (UIApplication.sharedApplication.applicationState != UIApplicationStateInactive) {
//Write your code her, this will get executed when your app is not in Inactive state.
}
am new to ios. If we receive a notification message as "Message: #"Welcome"" then i have to show only "Welcome" in the notification of ios device. Is it possible and how to do it ?
Thanks in advance for any help.
Whatever is sent in the payload of the push notification is displayed in the banner shown to the user. If you want to customize this message, you'll have to change what you are sending to the APNs service. See the push notification programming guide for details: https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Introduction.html#//apple_ref/doc/uid/TP40008194-CH1-SW1
At iOS (client) side you can only program what action to be taken when user clicks on notification or when user gets remote notification . For that you have to add code in the -
-(void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
But you will not have any control over the notification shown while your application is in background . For this you have to do string operations at server side from where you are sending the push .
You can do this while your app is in Foreground State using remove Some specific Characters. follow (how to remove first 3 characters from nsstring?) for reference.
But if you are in Background state you can not handle payload. so whatever text was send from APNs service. it will show in iOS.
Suggestion : you can send payload like below
aps = {
alert =
{
body = Welcome;
type = Message;
};
};
So you will know the type of payload and it will show only "Welcome".
I have implemented the APNS in my app. But I have two questions about it.
How to make the badge self-increase? In my app, it is always set to 1 now.
If a push notification arrives when the app is in foreground, as far as I know, I need to implement a altert view and play a sound by my self. In this case, is there any way to play the system default notification sound, i.e. when user change it in settings, it will change automatically.
Thanks.
you can increment the badge count as wasim described but it will only work if you app is in foreground, so for displaying correct badge count your server has to push correct badge number.
for playing default system notification sound when app is in foreground I dont think there is any APIs for that, for that you have put the sound file in your bundle and play that sound when notification receives.
In your AppDelegate.m use the following function:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
badge_value+=[[[userInfo objectForKey:#"aps"] objectForKey:#"badge"]intValue];
[UIApplication sharedApplication].applicationIconBadgeNumber = badge_value;
}
where, badge_value is an integer that stores the badge value.
Usually in all apps, the unread notification counts are maintained in the server. When the server sends a push notification to a particular device token server sends the badge count along with the payload.
Your server logic needs to keep track of the proper badge count and send it appropriately.
{
"aps" :
{
"alert" : "Your notification message",
"badge" : badgecount ,
"sound" : "bingbong.aiff"
}
}
I was wondering if it's possible to keep the last 5 (for example) read notifications in the apple's notification center (the one that shows up when you swipe down near the top)
I've noticed that once you click on a notification and "read" it, it disappears from the list. Is this done programaticaly by the app, who sends the device a message that the notification has been read and it's ok to delete it, or is it done automatically by the device and you have absolutely no control on it.
One client said it saw an app that did this and kept the last 5 notifications there, regardless if they were accessed or not but so far I've found nothing to indicate that this is possible
Well, it's not a very complete answer, but one of my colleagues managed to make this work.
All he did was to stop using badge number for notifications. No badge number is set when a notification is received, and no badge number is set when a notification is read.
[edit]It seems that when you set the badge number to 0 after you receive the notification, iOS automatically clears the notification, this being an undocumented feature.
You can only "read" the notifications sent to your App, and only if the user explicitly used their "action" button to open your App. if that was the scenario you can use:
// Handle local notification if received
if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey] != nil) {
NSLog(#"received a local notification = %#", [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]);
// Do something, save it..
}
// Handle remote notification if received
if ([launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey] != nil) {
NSlog(#"received a remote notification = %#", [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]);
// Do something, save it..
}
Or other alternatives (NotificationCenter etc) to read the notification when the app is opened with it and save it persistently.