I'm trying to figure out how I can examine the payload of a push notification in order to determine which view opens when a user opens the app from the notification. For example, if a notification says "x: test" view x would open when the notification is tapped and if the notification says "y: test" view y would open.
EDIT: I guess I should clarify the part I'm not sure about.
I have this in didFinishLaunchingWithOptions:
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (notification)
{
// check payload then load appropriate view controller
}
How would I check the payload for certain text in order to determine the appropriate view controller to load?
Here is my code from a past project. The notification shows up in device like this "Kostas: wants to add you as friend".
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
NSDictionary *remoteNotif =
[launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (remoteNotif) {
NSString *name = [[NSString alloc] init];
NSString *message = [[NSString alloc] init];
// 'wants to add you as friend.'
NSString* alertValue = [[remoteNotif valueForKey:#"aps"] valueForKey:#"alert"];
NSMutableArray* parts = [NSMutableArray arrayWithArray:[alertValue componentsSeparatedByString:#": "]];
name = [parts objectAtIndex:0];
[parts removeObjectAtIndex:0];
message = [parts componentsJoinedByString:#": "];
if ([message isEqualToString:#": wants to add you as friend."]) {
UITabBarController *tabController = (UITabBarController *)self.window.rootViewController;
// tabController.delegate = self;
tabController.selectedIndex = 1;
}
else{
UITabBarController *tabController = (UITabBarController *)self.window.rootViewController;
// tabController.delegate = self;
tabController.selectedIndex = 2;
[self addMessageFromRemoteNotification:remoteNotif updateUI:NO];
}
Receiving a push notification is handled in two places in the app delegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions when your app is launched from a push notification. In this case, your push notification data is contained within [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo when your app is running when receiving the notification. In this case, userInfo is your push notification data.
Related
I have an iOS application in which I am using the push notification to notify the user when the correct answer is posted. If the application is open and if I click on the notification it goes to the specified controller. But if the application is closed and if I receive the notification it does not goes to the specified controller.
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(#"User Info %#",userInfo);
NSString* alertValue = [[userInfo valueForKey:#"aps"] valueForKey:#"badge"];
NSLog(#"my message-- %#",alertValue);
int badgeValue= [alertValue intValue];
// NSNumber *identifierString = [[[userInfo valueForKey:#"aps"]valueForKey:#"details"]valueForKey:#"identifire"];
// NSLog(#"identifierString %#",identifierString);
NSString *alertMessage = [[userInfo valueForKey:#"aps"] valueForKey:#"alert"];
NSLog(#"ALertMessage %#",alertMessage);
if ([alertMessage isEqualToString:#"New answer added."]) {
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:badgeValue];
// [[NSUserDefaults standardUserDefaults] setObject:[[[[userInfo valueForKey:#"aps"] valueForKey:#"details"] objectAtIndex:0]valueForKey:#"question"]forKey:#"notificationQuestion"];
// [[NSUserDefaults standardUserDefaults] setObject:[[[[userInfo valueForKey:#"aps"] valueForKey:#"details"] objectAtIndex:0]valueForKey:#"user_image"]forKey:#"notificationImage"];
// NSLog(#"Image %#",[[NSUserDefaults standardUserDefaults]valueForKey:#"notificationQuestion"]);
NSLog(#"User Information %#",userInfo);
NSLog(#"User Details %#",[[userInfo valueForKey:#"aps"] valueForKey:#"details"]);
// NSLog(#"User Details 1%#",[[[userInfo valueForKey:#"aps"] valueForKey:#"details"] objectAtIndex:0]);
// NSLog(#"User Details 1%#",[[[[userInfo valueForKey:#"aps"] valueForKey:#"details"] objectAtIndex:0]valueForKey:#"question"]);
pushDictonary = [[userInfo valueForKey:#"aps"] valueForKey:#"details"];
}
//NSArray *pushDetails = [[userInfo valueForKey:#"aps"] valueForKey:#"details"];
// NSLog(#"Push Details %#",pushDetails);
if (application.applicationState == UIApplicationStateActive ) {
// UILocalNotification *localNotification = [[UILocalNotification alloc] init];
// localNotification.userInfo = userInfo;
// localNotification.soundName = UILocalNotificationDefaultSoundName;
// localNotification.alertBody = [[userInfo valueForKey:#"aps"] valueForKey:#"alert"];
// localNotification.fireDate = [NSDate date];
if ([alertMessage isEqualToString:#"New answer added."])
{
[self createNotificationViewwithUserDictionary:userInfo];
}
}
else if (application.applicationState == UIApplicationStateBackground)
{
NSLog(#"YES");
}
else if (application.applicationState == UIApplicationStateInactive)
{
NSLog(#"YES");
if ([alertMessage isEqualToString:#"New answer added."])
[self pushdetailsViewController];
}
For going to the controller :
-(void)pushdetailsViewController
{
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
QPYourQuestionController *controller = (QPYourQuestionController*)[mainStoryboard instantiateViewControllerWithIdentifier: #"yourQuestion"];
[[QPCommonClass initializeUserDefaults]setObject:[pushDictonary valueForKey:#"question_id"] forKey:#"currentquestionID"];
NSLog(#"Dictionary %#",pushDictonary);
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
[navigationController pushViewController:controller animated:YES];
}
For the situation when application is closed the remote notification delegate
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
is not called
In this case the call goes to the following method:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Hence you can do this to take the user to the VC you want
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// ...
if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {
// Do whatever you want
}
}
add this code to your app delegate file
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
//you will get notification data in userInfo dict
UIStoryboard * mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
notificationViewController * notificationVC = [mainStoryboard instantiateViewControllerWithIdentifier: #"notificationViewController"];//set your controller here
[(UINavigationController *)self.window.rootViewController pushViewController:notificationVC animated:YES];
completionHandler(UIBackgroundFetchResultNewData);
}
I am trying to send a local notification with a action button.
The notification is ok. But the action button is not displayed.
I am using Xcode 6.3.2 iPhone 6 iOS 8.2
Sending notification
UIApplication *myapp = [UIApplication sharedApplication];
UILocalNotification *test = [[UILocalNotification alloc] init];
if(test) {
NSLog(#"Sending notification");
test.alertBody = #"jothi test alert";
test.alertTitle = #"kottapa";
test.soundName = UILocalNotificationDefaultSoundName;
test.alertAction = NSLocalizedString(#"View Details", nil);
test.category = #"MY_CATEGORY";
[myapp presentLocalNotificationNow:test];
}
in app delegate didFinishLaunchingWithOptions:
UIMutableUserNotificationAction *myAction =
[[UIMutableUserNotificationAction alloc] init];
myAction.identifier = #"MY_IDENTIFIER";
myAction.title = #"Test Action";
myAction.activationMode = UIUserNotificationActivationModeBackground;
myAction.destructive = NO;
myAction.authenticationRequired = NO;
//------------
// First create the category
UIMutableUserNotificationCategory *inviteCategory =
[[UIMutableUserNotificationCategory alloc] init];
// Identifier to include in your push payload and local notification
inviteCategory.identifier = #"MY_CATEGORY";
// Add the actions to the category and set the action context
[inviteCategory setActions:#[myAction]
forContext:UIUserNotificationActionContextDefault];
// Set the actions to present in a minimal context
[inviteCategory setActions:#[myAction]
forContext:UIUserNotificationActionContextMinimal];
NSSet *categories = [NSSet setWithObject:inviteCategory];
UIUserNotificationSettings *settings =
[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound
categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
Your code works, you just needs to swipe the notification to the left in order to see the action button (or pull it down, if it's presented in a form of a banner from the top, when the device isn't locked).
Also, I'm guessing you already did that but just didn't include the code, in order to handle the action the user chose, you need to implement this method in your app delegate:
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void(^)())completionHandler
I recently use the Amazon SNS to push notification for my IOS app.
It works well, the only problem I have encountered is when I receive the notification , the badge number will not be updated, here is how I implement:
First I follow the example here
https://aws.amazon.com/articles/9156883257507082
, I extract only the SNS part that means I only alter the appdelegate in my app. Here is the example code from the tutorial.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
application.applicationIconBadgeNumber = 0;
NSString *msg = [NSString stringWithFormat:#"%#", userInfo];
NSLog(#"%#",msg);
[[Constants universalAlertsWithTitle:#"Push Notification Received" andMessage:msg] show];
}
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//Register for push notification
application.applicationIconBadgeNumber = 0;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
if(launchOptions!=nil){
NSString *msg = [NSString stringWithFormat:#"%#", launchOptions];
NSLog(#"%#",msg);
[[Constants universalAlertsWithTitle:#"Push Notification Received" andMessage:msg] show];
}
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
Message_BoardViewController *boardViewController = [Message_BoardViewController new];
UINavigationController *navigationController = [UINavigationController new];
navigationController.navigationBar.translucent = NO;
[navigationController pushViewController:boardViewController animated:NO];
[boardViewController release];
self.window.rootViewController = navigationController;
[navigationController release];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque];
[self.window makeKeyAndVisible];
// Logging Control - Do NOT use logging for non-development builds.
#ifdef DEBUG
[AmazonLogger verboseLogging];
#else
[AmazonLogger turnLoggingOff];
#endif
[AmazonErrorHandler shouldNotThrowExceptions];
return YES;
}
As you can see, the badge number will always become 0, and also I found the JSON incoming notification from SNS is without badge field but only has alert field, didReceiveRemoteNotification is not call when the app is at background too.
So , how can I modify the code to update the badge? Thanks for kindly help.
Hi i have added push notification in my application and I want to view particular ViewControllers when the user tap the notification. In my app delegate m file I'm trying to get the register the device token to my server and from my server I'm using the php script to get the device token from server and I'm sending the notification.
The problem here I'm trying to view a particular view controller when the user taps on the notification its not working i have tried many different methods nothing had worked.
Here I'm view the popup like to send notification from the app when user trying to install application for the first time.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeNone)];
return YES;
}
- (void) clearNotifications {
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
Here I'm storing the device to token to my server.
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
const char* data = [deviceToken bytes];
NSMutableString * token = [NSMutableString string];
for (int i = 0; i < [deviceToken length]; i++) {
[token appendFormat:#"%02.2hhX", data[i]];
}
NSString *urlString = [NSString stringWithFormat:#"url?token=%#",token];
NSURL *url = [[NSURL alloc] initWithString:urlString];
NSLog(#"token %#",urlString);
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSLog(#"request %# ",urlRequest);
NSData *urlData;
NSURLResponse *response;
urlData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:nil];
NSLog(#"data %#",urlData);
[self clearNotifications];
// NSLog(#"token ",sendUserToken);
}
Here I'm trying to view the particular method when user tap the notification.
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
updatepoliticalViewController *ringingVC = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:#"updatepoliticalViewController"];
[self.window.rootViewController presentViewController:ringingVC animated:YES completion:NULL];
}
My particular view controller name is updatepoliticalViewController its a navigation view controller please tell me in this above code where I'm doing wrong how to resolve this issue.
Thanks
When the app is in foreground state it call
application:didReceiveRemoteNotification:
but if it's not and the app is launched, for example, by swiping the alert in notification center
application:didFinishLaunchingWithOptions:
is called with key.
The good way is to call
application:didReceiveRemoteNotification:
from
application:didFinishLaunchingWithOptions:
I believe this should help
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {
[self application:application didReceiveRemoteNotification:launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]];
}
// YOUR CODE...
return YES;
}
// EXTENDED
Try get storyboard like that:
// Make sure the name match
UIStoryboard *mainstoryboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
Create your object from mainstoryboard:
updatepoliticalViewController *ringingVC = [mainstoryboard instantiateViewControllerWithIdentifier:#"updatepoliticalViewController"];
And try set new root view controller
[self.window setRootViewController: ringingVC];
1) When application is running in background and When application is running in foreground
application:didReceiveRemoteNotification: method will called as below.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if ( application.applicationState == UIApplicationStateInactive)
{
//opened from a push notification when the app was on background
NSLog(#"userInfo->%#",[userInfo objectForKey:#"aps"]);
}
else if(application.applicationState == UIApplicationStateActive)
{
// a push notification when the app is running. So that you can display an alert and push in any view
NSLog(#"userInfo->%#",[userInfo objectForKey:#"aps"]);
}
}
2) When application is not launched (close) than application:didFinishedLaunchWithOptionsmethod will called.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if (launchOptions != nil)
{
//opened from a push notification when the app is closed
NSDictionary* userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (userInfo != nil)
{
NSLog(#"userInfo->%#",[userInfo objectForKey:#"aps"]);
}
}
else{
//opened app without a push notification.
}
}
I'm developing a iOS app that manage Push Notifications. When a push comes up, the app badge is looking good, but where I'm having trouble is on the badges that appear inside the app. With inside the app i mean in the UITabBarItems that the app manages.
The app has a TabBarController where in two UITabBarItems a badge has to increment depending on wich Push Notification appeared. That is correctly handled in the server side, as I debuged and the push badge numbers comes ok. The thing is that the tab bar items are not updating ok.
Here's some part of my code:
This all happens inside de AppDelegate.m
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *user = [defaults stringForKey:#"id"];
if (user){
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle: nil];
UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:#"tabbar"];
self.window.rootViewController= viewController;
}
return YES;
}
And here's where I handle the push and update the badges in the uitabbaritem:
-(void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// Notify UAInbox to fetch any new messages if the notification
// contains a rich application page id.
if (application.applicationState != UIApplicationStateBackground) {
UA_LINFO(#"Received remote notification: %#", userInfo);
[[NSNotificationCenter defaultCenter] postNotificationName:#"refreshRequests" object:nil];
NSString* type = [userInfo objectForKey:#"type"];
if ([type isEqualToString:#"s"]){
[[[[(UITabBarController*)self.window.rootViewController viewControllers]
objectAtIndex: 2] tabBarItem] setBadgeValue:[[userInfo objectForKey:#"particularBadge"] stringValue]];
}else{
[[[[(UITabBarController*)self.window.rootViewController viewControllers]
objectAtIndex: 0] tabBarItem] setBadgeValue:[[userInfo objectForKey:#"particularBadge"] stringValue]];
}
}else{
// Notify UAPush that a push came in with the completion handler
[[UAPush shared] handleNotification:userInfo
applicationState:application.applicationState
fetchCompletionHandler:completionHandler];
}
[[NSNotificationCenter defaultCenter] postNotificationName:#"refreshRequests" object:nil];
[self clearNotifications];
}
When I debug it, the badge in [[userInfo objectForKey:#"particularBadge"] stringValue] is 1 for example, but when the code finished passing over there the uitabbaritem doesn't update. Sometimes it works ok, but others it doesn't and I can't figure out why.
When the app launches it asks if the user is logged..If not the self.window.rootviewController is a LoginViewController. I don't know if this information should be important.
Any help would be appreciated!