Enable push notifications via a UISwitch - ios

I want to use a UISwitch to enable/disable push notifications. Like in Tweetbot.
Does anyone know how to trigger that?

You can also do it in the following way.
create a IBOutlet for UISwitch
#property (strong, nonatomic) IBOutlet *pushNotificationSwitch;
and in Action method, store the value in NSUserDefaults.
- (IBAction)pushNotificationSwitchChanged:(id)sender
{
NSNumber *switch_value = [NSNumber numberWithBool:[self.pushNotificationSwitch isOn]];
[[NSUserDefaults standardUserDefaults] setObject:switch_value forKey:RECIEVE_APNS];
[[NSUserDefaults standardUserDefaults] synchronize];
}
and check it in viewdidload.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSNumber *sett = [[NSUserDefaults standardUserDefaults] valueForKey:RECIEVE_APNS];
if( [sett boolValue] )
{
[self.pushNotificationSwitch setOn:YES];
}
else{
[self.pushNotificationSwitch setOn:NO];
}
}
and In AppDelegate.m, add the following code
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSNumber *sett = [[NSUserDefaults standardUserDefaults] objectForKey:RECIEVE_APNS];
if( [sett boolValue] )
{
int currentBadgeCount = [[NSUserDefaults standardUserDefaults] integerForKey:#"BadgeCount"];
//Set the baadge count on the app icon in the home screen
int badgeValue = [[[userInfo valueForKey:#"aps"] valueForKey:#"badge"] intValue];
[UIApplication sharedApplication].applicationIconBadgeNumber = badgeValue + currentBadgeCount;
[[NSUserDefaults standardUserDefaults] setInteger:badgeValue + currentBadgeCount forKey:#"BadgeCount"];
NSString *alertString = [[userInfo objectForKey:#"aps"] objectForKey:#"alert"];
NSString *playSoundOnAlert = [NSString stringWithFormat:#"%#", [[userInfo objectForKey:#"aps"] objectForKey:#"sound"]];
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/%#",[[NSBundle mainBundle] resourcePath],playSoundOnAlert]];
NSError *error;
if (alertString.length > 0)
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"App Name" message:alertString delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 1;
[audioPlayer play];
[alert show];
}
}
}
enter code here

You can not do that directly from the application. If you want to do this, you need to make the UISwitch send the information to your backend, store this information in your database and stop sending push notifications to this user.

An app registers for Push Notifications (APN) when it first launches. You cannot have it initialize APNs with a switch once it has already launched. You can however code your app that a switch can choose to do "something" with the user interface once a APN is received.
For example, you can have this code:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSDictionary *apsInfo = [userInfo objectForKey:#"aps"];
NSString *alert = [apsInfo objectForKey:#"alert"];
// do what you need with the data...
[[NSNotificationCenter defaultCenter] postNotificationName:#"ReceivedNotificationAlert" object:self];
}
You can use your UISwitch to either do something, or not, with the NSNotification "ReceivedNotificationAlert". For example:
if(switchAPNprocess.on){
// process APN
}
else {
// ignore APN
}

Related

After removing alert view from didReceiveLocalNotification in active state,no notification is coming in foreground

I'm implementing local notifications,there are 3 notifications to be send at different times of a day.
in my app delegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
}
}
and in DidReceiveLocalNotifications
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
NSString *checkbtn= [[NSUserDefaults standardUserDefaults]valueForKey:#"on"];
if([checkbtn isEqualToString:#"SwitchOn"])
{
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Green Actions"
message:notification.alertBody
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
}
// Set icon badge number to zero
application.applicationIconBadgeNumber = 0;
//}
}
if i remove this alert view,i m not getting any notification in foreground but if i use this then i m getting notification alert every second.
this is my viewcontroller code
- (void)viewDidLoad {
[super viewDidLoad];
appdelegate= (AppDelegate *) [[UIApplication sharedApplication]delegate];
[self createCustomeNavigationBar];
self.navigationController.navigationBar.translucent = NO;
//[self notificationOne];
[self.switchbutton addTarget:self action:#selector(switchToggled:) forControlEvents:UIControlEventValueChanged];
[self.switchbutton1 addTarget:self action:#selector(switchToggled1:) forControlEvents:UIControlEventValueChanged];
[self.switchbutton3 addTarget:self action:#selector(switchToggled3:) forControlEvents:UIControlEventValueChanged];
if ([[NSUserDefaults standardUserDefaults]valueForKey:#"on"])
{
UILocalNotification* n1 = [[UILocalNotification alloc] init];
n1.fireDate = [NSDate dateWithTimeIntervalSinceNow: 160];
n1.alertBody = #"one";
[[UIApplication sharedApplication] scheduleLocalNotification: n1];
}
if ([[NSUserDefaults standardUserDefaults]valueForKey:#"SwitchOneon"])
{
UILocalNotification* n2 = [[UILocalNotification alloc] init];
n2.fireDate = [NSDate dateWithTimeIntervalSinceNow: 190];
n2.alertBody = #"two";
[[UIApplication sharedApplication] scheduleLocalNotification: n2];
}
// Do any additional setup after loading the view from its nib.
}
- (void) switchToggled:(id)sender {
self.switchbutton = (UISwitch *)sender;
if ([self.switchbutton isOn]) {
NSLog(#"its on!");
[[NSUserDefaults standardUserDefaults]setObject:#"SwitchOn" forKey:#"on"];
[[NSUserDefaults standardUserDefaults]synchronize];
} else {
[[NSUserDefaults standardUserDefaults]removeObjectForKey:#"on"];
NSLog(#"its off!");
}
}
- (void) switchToggled1:(id)sender {
self.switchbutton1 = (UISwitch *)sender;
if ([self.switchbutton1 isOn]) {
NSLog(#"its on!");
[[NSUserDefaults standardUserDefaults]setObject:#"SwitchOn" forKey:#"SwitchOneon"];
[[NSUserDefaults standardUserDefaults]synchronize];
} else {
[[NSUserDefaults standardUserDefaults]removeObjectForKey:#"SwitchOneon"];
NSLog(#"its off!");
}
}
- (void) switchToggled3:(id)sender {
self.switchbutton3 = (UISwitch *)sender;
if ([self.switchbutton3 isOn]) {
NSLog(#"its on!");
[[NSUserDefaults standardUserDefaults]setObject:#"SwitchOn" forKey:#"SwitchThreeon"];
[[NSUserDefaults standardUserDefaults]synchronize];
} else {
[[NSUserDefaults standardUserDefaults]removeObjectForKey:#"SwitchThreeon"];
NSLog(#"its off!");
}
}
and also i m getting some different text in alert view which i used earlier just for testing purpose,even after changing it,i m getting the same old previous text.
I am sure that problem isn't with alert code. - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification, you're getting notification. But when your app is in foreground (or active) you should handle it manually. In your case, you're handling it with UIAlertView so it will be visible in alert, but once you removed, you're not able to see a notification when your app was in foreground (or active) state.

Push Notification Payload not saved on some device

I'm having an issue handling the notification payload on some device. I'm sending push notifications to my users through Parse Cloud functions.
I'm using the below method to capture the notification and storing its payload so that the user can view all the received notifications in a dedicated view. On my personal device I always get the notification and it is saved correctly, on my friend's device though the notification arrive but if the App is in background the payload is not saved, while if the App is in foreground the payload is saved.
Can this be an issue of the device itself? Or maybe something related to the phone provider (I have h3g and he have Vodafone)?
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
// Parse push handler will show a UIAlertView
[PFPush handlePush:userInfo];
if (application.applicationState == UIApplicationStateInactive) {
// tha app is inactive, transitioning to or from the background
completionHandler(UIBackgroundFetchResultNoData);
} else if (application.applicationState == UIApplicationStateBackground) {
// tha app is running in background
// add the notification to the notificationsArrayRecord
NSDate *now = [[NSDate alloc]init];
NSDictionary *aps = userInfo[#"aps"];
NSString *alertMessage = aps[#"alert"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *notificationsArrayRecord = [[defaults arrayForKey:#"notificationsArrayRecord"] mutableCopy];
[notificationsArrayRecord addObject:#[now,alertMessage]];
[defaults setValue: notificationsArrayRecord forKey:#"notificationsArrayRecord"];
// update the notifications counter
NSInteger pushCount = [[NSUserDefaults standardUserDefaults] integerForKey: #"pushCount"];
pushCount ++;
[defaults setInteger: pushCount forKey:#"pushCount"];
[defaults synchronize];
completionHandler(UIBackgroundFetchResultNewData);
} else {
// the app is running in foreground
// add the notification to the notificationsArrayRecord
NSDate *now = [[NSDate alloc]init];
NSDictionary *aps = userInfo[#"aps"];
NSString *alertMessage = aps[#"alert"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *notificationsArrayRecord = [[defaults arrayForKey:#"notificationsArrayRecord"] mutableCopy];
[notificationsArrayRecord addObject:#[now,alertMessage]];
[defaults setValue: notificationsArrayRecord forKey:#"notificationsArrayRecord"];
// update the notifications counter
NSInteger pushCount = [[NSUserDefaults standardUserDefaults] integerForKey: #"pushCount"];
pushCount ++;
[defaults setInteger: pushCount forKey:#"pushCount"];
[defaults synchronize];
completionHandler(UIBackgroundFetchResultNewData);
// refresh the menu buttons and the notification counter
[[NSNotificationCenter defaultCenter] postNotificationName:#"appDidReceiveNotificationWhileActive" object:nil];
}
}
I guess the problem is how you handle the application state UIApplicationStateInactive. In this case, you are not storing the information. You should also store it in this case, because the app can apparently be in this state, when you receive notifications. This also explains, why it fails sometimes.
Also see this question, that states the app is in state UIApplicationStateInactive sometimes, when the device receives a notification.
You should refactor your code to store the data in all cases:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
// Parse push handler will show a UIAlertView
[PFPush handlePush:userInfo];
// add the notification to the notificationsArrayRecord
NSDate *now = [[NSDate alloc]init];
NSDictionary *aps = userInfo[#"aps"];
NSString *alertMessage = aps[#"alert"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *notificationsArrayRecord = [[defaults arrayForKey:#"notificationsArrayRecord"] mutableCopy];
[notificationsArrayRecord addObject:#[now,alertMessage]];
[defaults setValue: notificationsArrayRecord forKey:#"notificationsArrayRecord"];
// update the notifications counter
NSInteger pushCount = [[NSUserDefaults standardUserDefaults] integerForKey: #"pushCount"];
pushCount ++;
[defaults setInteger: pushCount forKey:#"pushCount"];
[defaults synchronize];
if (application.applicationState == UIApplicationStateInactive) {
// the app is inactive, transitioning to or from the background
completionHandler(UIBackgroundFetchResultNoData);
} else if (application.applicationState == UIApplicationStateBackground) {
// the app is running in background
completionHandler(UIBackgroundFetchResultNewData);
} else {
// the app is running in foreground
completionHandler(UIBackgroundFetchResultNewData);
// refresh the menu buttons and the notification counter
[[NSNotificationCenter defaultCenter] postNotificationName:#"appDidReceiveNotificationWhileActive" object:nil];
}
}
Update:
I am not sure about calling completionHandler(UIBackgroundFetchResultNoData) in applicationState (no idea what this is good for), but maybe you need to call completionHandler(UIBackgroundFetchResultNewData) instead, also in this case, to get the data stored.
Also make sure you configured everything properly to receive notifications in background, [see this] answer(https://stackoverflow.com/a/31450953/594074).

Displaying alert from app delegate before displaying alert from viewDidload

I am attempting to display the message contained within a push notification through the app delegate as outlined in the parse.com documentation.
The problem I am having is that in my viewdidload method for my first view controller, i am presenting an alert which the user MUST see before they use the app.
How can I call the method from my app delegate after the user sees the Alert from the viewdidload method?
EDIT:
So i have, as suggested in the comments, added a global Variable which i set to true once i have Displayed the alert from my ViewDidload method, but the Notification Alert from my appDelegate still does not appear.
here is my app delegate.m file:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
[Parse setApplicationId:#"xxxxxxxxxxxxxxxx"
clientKey:#"xxxxxxxxxxxx"];
// Register for Push Notitications, if running iOS 8
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes
categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
} else {
// Register for Push Notifications before iOS 8
[application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeSound)];
}
return YES;
NSDictionary *notificationPayload = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
if (Notification == true) {
if (![pushText isEqual: #""]) {
pushText = [[notificationPayload objectForKey:#"aps"] objectForKey:#"alert"];
UIAlertView *alert_news = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"News", "")
message:pushText
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert_news show];
}
}
}
And here is my viewdidload method:
RoadSafetyAppAppDelegate *AppDelegate;
- (void)viewDidLoad
{
AppDelegate = (RoadSafetyAppAppDelegate *)[[UIApplication sharedApplication] delegate];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
backgroundImage.alpha = 0.3;
toRecipients = [[NSArray alloc]initWithObjects:#"records#shellharbour.nsw.gov.au", nil];
static int appCounter;
if ( appCounter < 1 ) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Disclaimer", "")
message:NSLocalizedString(#"Using a mobile phone whilst driving is against the law. Ensure that you are not behind the wheel when using this app.", "")
delegate:nil
cancelButtonTitle:#"I agree to not use a mobile phone while driving"
otherButtonTitles: nil];
[alert show];
appCounter = appCounter+1;
AppDelegate.NotificationAlert = #"1";
AppDelegate.Notification = true;
}
}
since you want to show the disclaimer ONE time and to be sure that the user saw it and TAPED on Agree Button before showing any notification. you can do that using a simple local notification.
in delegate (...didFinishLaunchingWithOptions:)
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
//......you code here
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"disclaimerShown"]==nil)
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:#"disclaimerShown"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
//......you code here
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"disclaimerShown"]){ //YES
if (![pushText isEqual: #""]) {
pushText = [[notificationPayload objectForKey:#"aps"] objectForKey:#"alert"];
UIAlertView *alert_news = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"News", "")
message:pushText
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles: nil];
[alert_news show];
}
}
}
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
NSString *value=[NSString stringWithFormat:#"%#",[notification.userInfo valueForKey:#"key"]];
if ([value isEqualToString:#"disclaimerShown"]) {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"disclaimerShown"];
[[NSUserDefaults standardUserDefaults] synchronize];
///continue handle parse.com notification
}
}
in you ViewController:
-(void)viewDidLoad{
//...
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"disclaimerShown"]==NO){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(#"Disclaimer", "")
message:NSLocalizedString(#"Using a mobile phone whilst driving is against the law. Ensure that you are not behind the wheel when using this app.", "")
delegate:nil
cancelButtonTitle:#"I agree to not use a mobile phone while driving"
otherButtonTitles: nil];
alert.tag = 1;
[alert show];
}
//...
}
pragma mark - UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView.tag == 1) {//the disclaimer alert
if (buttonIndex == 0) {
UILocalNotification *alarm = [[UILocalNotification alloc] init];
alarm.userInfo = #{#"key": #"disclaimerShown"};
alarm.fireDate = [NSDate date];
alarm.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:alarm];
}
}
}
Instead of AppDelegate bool flag property use NSUserDefaults;
In AppDelegate update this line from:
if (Notification == true)
to
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"Notification"] == YES)
And in ViewController -> viewDidLoad method update line from:
AppDelegate.Notification = true;
to
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"Notification"];
[[NSUserDefaults standardUserDefaults] synchronize];
Hope this helps.

How to pass the device token from AppDelegate to UIViewController

Hi in my application I'm fetching the device token and I'm passing to my server to send the notification now I want to send the individual notification for the i need to fetch the device token form my UIViewController Please tell is there any possibilities fetching the device token form the Appdelegate or from the UIViewController
My code for fetching the device token in Appdelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeNone)];
return YES;
}
Device Token.
-(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);
}
I have used the to get the device token please tell me how to pass the device token to my UIViewController or how to fetch the device token from my UIViewController.
Use the NSUserDefaults to store the objects(values), you can access it anywhere.
AppDelegate (setValue) :
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
[[NSUserDefaults standardUserDefaults] setObject: token forKey:#"deviceID"];
[[NSUserDefaults standardUserDefaults]synchronize];
}
UIViewController (getValue) :
[[NSUserDefaults standardUserDefaults] objectForKey:#"deviceID"];
In AppDelegate.m class:
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
NSLog(#"My token is: %#", deviceToken);
NSString *device = [deviceToken description];
device = [device stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"<>"]];
device = [device stringByReplacingOccurrencesOfString:#" " withString:#""];
NSLog(#"My device is: %#", device);
[[NSUserDefaults standardUserDefaults] setObject:device forKey:#"MyAppDeviceToken"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
In ViewController class, inside viewDidLoad method:
[super viewDidLoad];
NSString *deviceToken = [[NSUserDefaults standardUserDefaults] objectForKey:#"MyAppDeviceToken"];
NSLog(#"device token in controller: %# ", deviceToken);
This is working perfectly in my device. Happy Coding !! :)
Try this coding in your view did load
NSString* deviceId = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
deviceId = [deviceId stringByReplacingOccurrencesOfString:#"-" withString:#""];
NSLog(#"%#",deviceId);
Declare and define below methods in your delegate file,
#pragma mark - Get / Set Device Token
+ (void)setDeviceToken:(NSString *)token {
if(token) {
[[NSUserDefaults standardUserDefaults] setObject:token forKey:#"DeviceToken"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
+ (NSString *)getDeviceToken {
NSString *token = [[NSUserDefaults standardUserDefaults] objectForKey:#"DeviceToken"];
if(token) {
return token;
}
return #"";
}
In -(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken method
call, [AppDelegate setDeviceToken:token]; once you get the token and
Now in project, in any view controller, you can call NSString *token = [AppDelegate getDeviceToken]; to get saved token, here note that, we call it with AppDelegate its name of your delegate file, and we call it with the class name, as we make a class method to set and get a token.
At the time of getting you can check for availability of saved token
NSString *token = [AppDelegate getDeviceToken];
if(token.length) {
// do something
}
You can get appDelegate instance in any view contoller and fetch value from that instance like -
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

Handling Apple Push Notification Service

I'm using apple push notification service in my project.
Please follow the 2 ways of opening the app and handling this push notifications. In the second scenario I do not know how to handle it. Do you know how?
The push notification arrived to my device,
Scenario 1:
I clicked on the push notification.
The - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo function AppDelegate.m file catches this function.
Scenario 2:
I normally opened the device (by clicking on the app)
How can I handle the push notification?
The other answers show how to get the notification data when the user taps the notification.
The difference between the two nethods shown is that one is called when app is already running, either in foreground or background, while the other is called when app is not running at all.
On your second case, when the user doesn't tap the notification, the notification data isn't passed to the app when you open it with the launch Icon.
First scenario:
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
{
NSLog (#"APNS: notification received: %#", userInfo);
NSString *message = nil;
id alert = [userInfo objectForKey:#"aps"];
if ([alert isKindOfClass:[NSString class]])
{
message = alert;
}
else if ([alert isKindOfClass:[NSDictionary class]])
{
message = [alert objectForKey:#"alert"];
}
if (message)
{
if (![message isEqualToString:#""])
{
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle: #"notification"
message: message
delegate: nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}
}
Second scenario:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSLog (#"LAUNCH OPTIONS: %#",launchOptions);
id remoteNotificationValue = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (remoteNotificationValue)
{
NSString *message = nil;
id alert = [remoteNotificationValue objectForKey:#"aps"];
if ([alert isKindOfClass:[NSString class]])
{
message = alert;
}
else if ([alert isKindOfClass:[NSDictionary class]])
{
message = [alert objectForKey:#"alert"];
}
if (message)
{
if (![message isEqualToString:#""])
{
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle: #"notification"
message: message
delegate: nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}
}
....
Of course you might want to make a special method that handles notifications and is called from both scenarios (with NSDictionary * parameter) so your code would be more readable. Sometimes APNS notifications are useful also when app is running - empty notification (with no payload) might be used to trigger the data synchronization with server to avoid polling for example.
You can get the arrived notifications when the app starts with the following code (e.g: in application:didFinishLaunchingWithOptions):
NSDictionary *remoteNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
Here is a more thorough explanation: How to manage notification when users click on badge
You can handle that like this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Checking if app was launched from the notification
if (launchOptions != nil) {
NSDictionary *dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (dictionary != nil){
// Read dictionary and do something since the app
// was launched from the notification.
}
}
Here is an example of what the dictionary object contains
NSString *message = #"";
NSString *badge = #"";
NSString *sound = #"";
if([dictionary objectForKey:#"alert"]) {
message = [dictionary objectForKey:#"alert"];
}
if([dictionary objectForKey:#"badge"]) {
badge = [dictionary objectForKey:#"badge"];
}
if([dictionary objectForKey:#"sound"]) {
sound = [dictionary objectForKey:#"sound"];
}
Hope it helps!

Resources