My app is close ,and screen is lock,when I receive a remote push notification,it appear on the screen,when I slide the notification but not slide the lock,it can open my app,all is OK.but the notification always appear at notification center,not disappear. How to dismiss it from the notification center,when I slide the notification.
(void)applicationDidFinishLaunching:(UIApplication *)application{
// put receive remote notification is here
}
is there have some api like cancel localnotificationg,cancel remote notification?
Set the applicationIconBadgeNumber property of your UIApplucation object to zero. This will clear tge notifications from notification center.
Where you handle the notification, you need to reset applicationIconBadgeNumber property.
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
This should be ideally at the place of Custom Code in following snippet:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(#"Received notification: %#", userInfo);
//[self addMessageFromRemoteNotification:userInfo];
NSString* alertValue = [[userInfo valueForKey:#"aps"] valueForKey:#"badge"];
NSLog(#"my message-- %#",alertValue);
badgeValue= [alertValue intValue];
[UIApplication sharedApplication].applicationIconBadgeNumber += badgeValue;
//
//Custom Code where you actually respond to the notification.
//
}
Related
I have been advised that I should allow users to turn push notifications on and off from within my app. I am using Parse to manage my push notifications. I have everything setup so that a user can register for notifications by pressing "Allow." when the push alert pops up. My question though, is about how I would permit the user to turn push notifications ON from within the app if they had originally said "Don't Allow." I know that the push notification alert will only display once. Does anyone have any ideas? Thanks!
My App Delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:
(NSDictionary *)launchOptions {
[Parse setApplicationId:#"APP_ID"
clientKey:#"CLIENT_KEY"];
[PFAnalytics trackAppOpenedWithLaunchOptions:launchOptions];
//other code
}
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
// Store the deviceToken in the current installation and save it to Parse.
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:deviceToken];
[currentInstallation saveInBackground];
}
User Settings View Controller:
-(IBAction) switchValueChanged {
if (toggleSwitch.on) {
[[UIApplication sharedApplication]
registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound)];
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
[currentInstallation setDeviceTokenFromData:deviceToken];
[currentInstallation saveInBackground];
}
else {
}
}
You cannot do that. The user has to manually go into the Notification Settings and set your app for notifications. Apparently the reason being is that Apple does not want an app pestering a user to allow if the user has already said no once.
I suggest having your app display an alert to advise the user of turning notifications on.
I am creating a local UILocalNotification and displaying it to the user as a banner. Is it possible to set it up so that when the user taps it and returns to the app, the app will receive some kind of data on the specific kind of notification it was? I want to open a specific view controller in the app. I think the best way would be to essentially send a URL to the app, or is there a way to get access to the UILocalNotification so that I can test which kind is was and do the right action?
To get data from the local NSUserNotification that is passed to an iOS app, all that you need to do is implement the following method: - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification.
The problem is, this is called both when a local notification is posted when the app is in the background (i.e. when the user taps on the notification and then returns to the app), and also if the app is in the foreground at the time when the local notification fires (it is on a timer, after all). So how should one figure out if the notification was fired when the app was in the background or foreground? It's pretty simple. Here's my code:
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateInactive) {
// Application was in the background when notification was delivered.
} else {
// App was running in the foreground. Perhaps
// show a UIAlertView to ask them what they want to do?
}
}
At this point you can handle the notification based on notification.userInfo, which holds a NSDictionary.
ust implement the NSUserNotificationCenterDelegate and define this method:
- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
Example:
This is what I did in a "notifier" application.
- (void) userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
{
NSRunAlertPanel([notification title], [notification informativeText], #"Ok", nil, nil);
}
- (void) userNotificationCenter:(NSUserNotificationCenter *)center didDeliverNotification:(NSUserNotification *)notification
{
notifications=nil;
[tableView reloadData];
[center removeDeliveredNotification: notification];
}
When the notification is activated (click by the user) I just inform the user with a panel (I could use a hud window).In this case I immediately remove the delivered notification, but this is not what happens usually.The notification could stay there some time and be removed after 1/2 hours (it depends on the application that you are developing).
1 - Define some class in your project to implement NSUserNoficationCenterDelegate protocol (documented here)
#interface someObject : NSObject <NSUserNotificationCenterDelegate>
{
- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification;
}
2 - Set an instance of the object defined #1 as the delegate of default notification center.
[[NSUserNotificationCenter defaultNotificationCenter] setDelegate: someObject];
Now you will get called on didActivateNotification any time the user taps/clicks on the notification. You will have the original notification you created. So any information that you need should be available to you.
If you want/need special information (other than notification title, message, etc) you will probably need to set additional application specific information in your notification before you schedule it to be sent. For example:
NSUserNotification* notification = [[NSUserNotification alloc] init];
NSDictionary* specialInformation = [NSDictionary dictionaryWithObjectsAndKeys: #"specialValue", #"specialKey", nil];
[notification setUserInfo:specialInformation];
I have studied some of the following questions, that are::
1.) How to set alarm for selected days in iphone?
2.) iPhone alarm using repeated local notifications
3.) How to set the alarm in iPhone and save in local notification?
but they all are using local notifications. I am facing problem with local notification as I have to use three buttons on an Alarm View which are: Snooze, Ignore and Okay. I have to perform custom actions on each button click.
Please help me with this stuff.
Suggestions accepted.
Thanks in advance.
Kuldeep.
In you app delegate...
- (void) presentWidget: (NSString*)theDisplayedText {
BOOL widgetIspresent = [WidgetVC widgetIsCurrentlyPresented];
if (!widgetIspresent) {
WidgetVC *widgetVC = [[WidgetVC alloc] initWithNibName:#"WidgetVC" userInfoString:theDisplayedText bundle:nil];
widgetVC.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
widgetVC.userInfoStr = theDisplayedText;
[mainScreenManager presentViewController:widgetVC animated:YES completion:nil];
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UILocalNotification *localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotif) {
NSLog(#"Recieved Notification didFinishLaunchingWithOptions %#",localNotif);
NSString *theDisplaytext = [localNotif.userInfo valueForKey:#"someKey"];
//here we have to handle whatever notification was pressed - that might also be an old aready passed one
//this all is checked when the widget opens - it will show if the notification is OK or too old
[self presentWidget: theDisplaytext ];
} else {
//so we started the app normally, not via local notification
[self presentWidget];
}
return YES;
}
// Handle the notificaton when the app is running
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)localNotif {
// Handle the notificaton when the app is running
NSLog(#"Recieved Notification didReceiveLocalNotification %#",localNotif);
NSString *theDisplaytext = [localNotif.userInfo valueForKey:#"someKey"];
[self presentWidget: theDisplaytext];
}
You need a way to start the UIViewController for the widget, I just created a mainScreenManager helper.
So on the widgetVC you have your "Snooze" and "OK" while the "Ignore" is just the ignoring of the notification itself.
Hope this gets you on an usable track...
ps I ported my app from Android to iPhone, that's why I used the name "widgetVC" for this screen. On Android it is implemented as a widget. Hope no iPhone lover feels offended :-)
Is it possible to increment the badge value on receiving the notification. OR Should I send the count as payload?
If i am sending the badge value as "1" every time, how could i increment the badge-value in the icon of the app if the app is not open.
i have used this code but doesn't work.
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[UIApplication sharedApplication].applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber + 1;
}
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 they send the badge count along with the payload. Once the device is notified and your app is in background(or killed) the OS automatically update the badge count to your app icon. In case whether you have your app running, you will get notified in the
application:didReceiveRemoteNotification:
delegate and thus you are able to receive the badge count from the (NSDictionary *)userInfo. And thus you are able to update the app icon badge count using the function
[UIApplication sharedApplication].applicationIconBadgeNumber = [[[userInfo objectForKey:#"aps"] objectForKey: #"badgecount"] intValue];
Think this should help you.
If the application is not open you will not be able to increase the badge except from the payload.
When a Push Notification comes while your application is in background mode & you want to increment the Badge Number, you should send a badgeCount to the server, so that the server knows the current count.
If you manage the badge count from the Server Side then this code is enough:-
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(#"remote notification: %#",[userInfo description]);
if (userInfo) {
NSLog(#"%#",userInfo);
if ([userInfo objectForKey:#"aps"]) {
if([[userInfo objectForKey:#"aps"] objectForKey:#"badgecount"]) {
[UIApplication sharedApplication].applicationIconBadgeNumber = [[[userInfo objectForKey:#"aps"] objectForKey: #"badgecount"] intValue];
}
}
}
}
Urban Airship supports this using their "autobadge" feature.
After receiving remote Notification when you open App,
get current Badge number in "didBecomeActive" Method of your Appdelegate File using below code:
int badgeCount = [UIApplication sharedApplication].applicationIconBadgeNumber;
badgeCount = badgeCount + 1;
These kind of question has been asked a number of times but i have some specific situation going on.
When my application is active and I receive a PUSH message i'm successfully able to parse the custom payloads and such.
However when my application is in the background and the PUSH arrives the user has to click on the 'View/Open' button in order to get the didReceiveRemoteNotification called and the didFinishLaunchingWithOptions is called after that.
I need to have my application decide if they have to prompt the user with an UIAlert when in the background or suppress the push message based on some local settings.
Any help would be appreciated,
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
...
}
You have to do several things in order to manage the received push notification when the app is in background.
First, in your server side, you have to set {"aps":{"content-available" : 1... / $body['aps']['content-available'] =1; in the push notification payload.
Second, in your Xcode project, yo have to habilitate "remote notifications". It is made by going to the project's target -> capabilities, then enable the capabilities switch, and check the remote notifications checkbox.
Third, instead of using didReceiveRemoteNotification, you have to call application:didReceiveRemoteNotification:fetchCompletionHandler:, this will allow you to do the tasks that you want in the background, at the moment of receiving the notification:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
if(application.applicationState == UIApplicationStateInactive) {
NSLog(#"Inactive - the user has tapped in the notification when app was closed or in background");
//do some tasks
[self manageRemoteNotification:userInfo];
completionHandler(UIBackgroundFetchResultNewData);
}
else if (application.applicationState == UIApplicationStateBackground) {
NSLog(#"application Background - notification has arrived when app was in background");
NSString* contentAvailable = [NSString stringWithFormat:#"%#", [[userInfo valueForKey:#"aps"] valueForKey:#"content-available"]];
if([contentAvailable isEqualToString:#"1"]) {
// do tasks
[self manageRemoteNotification:userInfo];
NSLog(#"content-available is equal to 1");
completionHandler(UIBackgroundFetchResultNewData);
}
}
else {
NSLog(#"application Active - notication has arrived while app was opened");
//Show an in-app banner
//do tasks
[self manageRemoteNotification:userInfo];
completionHandler(UIBackgroundFetchResultNewData);
}
}
Finally, you have to add this notification type: UIRemoteNotificationTypeNewsstandContentAvailability to the notifications settings when you set it.
Apart from this, if your app was closed when the notification arrived, you have to manage this in didFinishLaunchingWithOptions , and just if the user taps on the push notification: The way of do it is:
if (launchOptions != nil)
{
NSDictionary *dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (dictionary != nil)
{
NSLog(#"Launched from push notification: %#", dictionary);
[self manageRemoteNotification:dictionary];
}
}
launchOptions is != nil when you launch the app by tapping on the push notification, if you access it by tapping on the icon, launchOptions will be == nil.
I hope it will be useful. Here it is explained by Apple.
Pass content-available = 1 with your payload, and will invoke didReceiveRemoteNotification even in background. e.g.
{
"alert" : "",
"badge" : "0",
"content-available" : "1",
"sound" : ""
}
One thing to keep in mind, when your push message arrives at the user's iPhone and they click "cancel", except for the icon badge number (they'll be taken care of by the OS), there would be no way for your in-the-background app to know about this push event and take any further actions.
Word of warning
I think your app logic is basing behavior on custom data in your push notification. This is not what push notifications are intended for. What you should alternatively do on didbecomeactive in your application is just ask your server for the data you need and was sending as payload anyway, and rely on that instead of your payload.
Because the documentation also states that as best practice. Because Apple does not guarantee your push notification from being received 100% of the times anyway.
Important: Delivery of notifications is a “best effort”, not
guaranteed. It is not intended to deliver data to your app, only to
notify the user that there is new data available.
However, if you want to have some indication of whether for instance the badge has been changed without relying on a user opening the app by clicking on the badge you could something like this:
A. you add a (correct) badge number to the payload of the push notification sent by your server. It for instance could look like this:
{
"aps" : {
"alert" : "You got your emails.",
"badge" : 9
}
}
B. you keep track of that badge number persistently in your app, for instance by storing it in NSUserDefaults.
Then in applicationDidBecomeActive can compare the applicationIconBadgeNumber property of UIApplication with your previously stored badge count and see if it has been increased or decreased and do some updates based on that.
- (void)applicationDidBecomeActive:(UIApplication *)application
{
NSNumber *badgecount = [[NSUserDefaults standardUserDefaults] objectForKey:#"badgecount"];
if (!badgecount) badgecount = #(0);
if ([UIApplication sharedApplication].applicationIconBadgeNumber != [badgecount integerValue]) {
//store the new badge count
badgecount = [NSNumber numberWithInteger:[UIApplication sharedApplication].applicationIconBadgeNumber];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:badgecount forKey:#"badgecount"];
[defaults synchronize];
// do some stuff here because it's different
}
}
As of recent iOS - I think 8 - if you've got remote notifications enabled as a background mode, one trick is to track whether you're entering the foreground as a flag.
#interface AppDelegate ()
#property (assign, atomic, getter=isEnteringForeground) BOOL enteringForeground;
#end
- (void) applicationWillEnterForeground: (UIApplication *) application
{
self.enteringForeground = YES;
}
- (void) applicationDidBecomeActive: (UIApplication *) application
{
self.enteringForeground = NO;
}
- (void) application: (UIApplication *) application didReceiveRemoteNotification: (NSDictionary *) userInfo fetchCompletionHandler: (void (^) (UIBackgroundFetchResult)) completionHandler
{
const BOOL launchedFromBackground = !(application.applicationState == UIApplicationStateActive);
const BOOL enteringForeground = self.enteringForeground;
if (launchedFromBackground && enteringForeground) {
// The user clicked a push while the app was in the BG
}
}