Questions about APNS - ios

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"
}
}

Related

How handle silent push notification when application is InActive state in ios 9?

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.
}

didReceiveRemoteNotification no called in background although content_available = true

I use push notification in my app ,It is work fine but I want to receive notification if my app in background but method didReceiveRemoteNotification not called
I mad that
1- enable Background Mod
2- check remote notification
3- put content_available = true in data payload
and also when I test it from fcm dashboard not work ,
Please can anyone help me , Thanks.
If you're testing on iOS 10, content_available must be in JSON value of notification key, not in data key. Although for iOS <= iOS 9, content_available can be in JSON value of data or notification.
There's a typo in your code. It's not "content_available", the correct key is "content-available".
When you send "content-available" = 1, didReceiveRemoteNotification will be called.
You app needs to handle all the possible push notification delivery states:
Your app was just launched
Your app was just brought from background to foreground
Your app was already running in the foreground
You do not get to choose at delivery time what presentation method is used to present the push notification, that is encoded in the notification itself (optional alert, badge number, sound). But since you presumably are in control of both the app and the payload of the push notification, you can specify in the payload whether or not there was an alert view and message already presented to the user. Only in the case of the app is already running in the foreground do you know that the user did not just launch your app through an alert or regularly from the home screen.
You can tell whether your app was just brought to the foreground or not in didReceiveRemoteNotification using this bit of code:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if ( application.applicationState == UIApplicationStateActive )
// app was already in the foreground
else
// app was just brought from background to foreground
...
}
for further reference. Please check
didReceiveRemoteNotification when in background

How can I get array of arrived Remote Notifications in iOS when the application open?

I'm currently developing an iOS application that receive push notification from the web server.
I can receive my notification just fine when the application run in the background / foreground, but when the device is receiving notification while my application got terminated (swiped from the multitasking mode or lock the device), the DidReceiveRemoteNotification method doesn't get called (but the notification & banner does appear!).
So I'm thinking about getting all the arrived (unread) notification and clear all of them when the user launch the application (at FinishedLauncing method) and then I can display some of the message first, because fetching the data from the server do takes some time.
I do can get one message from the launchOptions if the user clicked on one of the notification to open my apps. But is there a way to get them all?
This is not possible to get all the notifications you received.
You can only receive payload of notification on which user tapped or selected from the notification center.
But there is a way, using that you can process your every push notification.
add key content-available with value 1 in to your aps dictionary.
so it will look like,
{
"aps" : {
"alert" : {
"title" : "Game Request",
"body" : "Bob wants to play poker",
},
"badge" : 5
"content-available" : 1
}
}
If iOS system detects pushNotification with this key having value 1,
it will call application:didReceiveRemoteNotification:fetchCompletionHandler: of your appDelegate.
userInfo is the dictionary containing push notifications. aps is the key for push notifications body.
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(#"userInfo %#",userInfo);
// you can get the required message as below
NSString *msg = [userInfo valueForKey:#"aps"];
NSLog(#"Push Notification:%#",msg);
}

Set App Icon badge no in IOS

I'm Working on PushNotification, I want to manage AppIconBadge no. in IOS.
Badge no is Receiving From parse Site, Suppose Badge no. received from parse id 20. now 20 will show on App logo when the app in background and kill State. i want it show only counting that is Remaining to read in the Notification Center. please help me how can i Manage the App Icon badge no.
App is kill state,one push notification arrived , then Which Function Called by IOS. Can i Control that Function
In kill state you can't access it. You should manage this number from parse before you send the push. to change badge number from the app itself:
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: wantedNumber];
you can handle you badge count in app delegate.m didReceiveRemoteNotification method
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
alert = userInfo[#"aps"][#"alert"];
//Handle you badge count here
}
Badge number comes in payload. You need to increment the badge number at server and keep a track of badge number there itself. On receiving any notification if you open the app the badge count should be reset to any value that you can do # setApplicationIconBadgeNumber.
On app launch reset the counter to 0 or whatever you want at your server thru a network request, so that the next notification send a payload with badge number from 0.

Silently send push notifications from my server to my app

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)")
}
}

Resources