Push notification data retrieving - iphone

I want to get data from push notification message. I successfully get the data when app is on foreground and in background. but I am unable to get data when app is quit and user press view button on push notification. I write the code in application did finish launching. This code cause the app crash when pressing on View button of push notification message. If I comment the code then app doesn't crash. Kindly help me to fetch data from push notification when app is quit and user press view button on push notification. I'll really appreciate that.
if(launchOptions != nil){
NSDictionary *tmpDic = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (tmpDic!=nil) {
pushedMessage=[NSString stringWithFormat:#"%#",[[tmpDic objectForKey:#"aps"] objectForKey:#"alert"]];
pushedCountry=[NSString stringWithFormat:#"%#",[tmpDic objectForKey:#"country"]];
[self saveToDatabase];
}
}

Please try this...
Add this code to appdelegate.m => didFinishLaunchingWithOptions
if ([launchOptions valueForKey:#"UIApplicationLaunchOptionsRemoteNotificationKey"]) {
[self application:application didReceiveRemoteNotification:launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]];
}

From ios7 we have the below delegate method to handle the push notification when the app is in back ground or not running
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler

When you click view button
- (void)application:(UIApplication*)application didReceiveRemoteNotification: (NSDictionary*)userInfo
{
}
this method is called and userinfo will contain all data
Things which you are doing in didfinishlaunch method do in didReceiveRemoteNotification:

I don't totally understand what your asking but you can do stuff with what is being being push with a function in the app delegate
- (void)application:(UIApplication*)application didReceiveRemoteNotification:
(NSDictionary*)userInfo
{
NSLog(#"Received notification: %#", userInfo);
[self addMessageFromRemoteNotification:userInfo updateUI:YES];
}
Now you can add that data to core data or sqlite. This may not be relevant to your question but it's the best I can give based on what you've asked in your question.

See my comment on the above answer.
Here is Apple's doc:
If the app is not running when a push notification arrives, the method
launches the app and provides the appropriate information in the
launch options dictionary. The app does not call this method to handle
that push notification. Instead, your implementation of the
application:willFinishLaunchingWithOptions: or
application:didFinishLaunchingWithOptions: method needs to get the
push notification payload data and respond appropriately.
So you need to implement:
- (void)application:(UIApplication*)application didReceiveRemoteNotification:
(NSDictionary*)userInfo
As well as handling the launchOptions in:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

Related

how to retrieve and handle remote push notification content in iOS app

I was trying to fetch remote notification info when the app was not running,so I was told that I can get from :
UILocalNotification *localNotification = [launchOptions
objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]
in method:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
,but still can't get info.
Then I use alertView to show the info on iPhone(launch without Xcode),still can't get the info.
Any other issue would cause this? Please let me know if you have any ideas.
How to retrieve and handle remote notifications:
app is running
The userInfo in below method already includes the push notification
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
}
app not running
The value for key in launchOptions includes the push notification,under two circumstance:
1.screen is locked,when receive the remote push notification,screen is lighted and user unlock the screen then directly launch the app.
2.user tap on the notification on the drop-down menu to launch the app.
If user tap on the app directly,then the notification will be gone and missed.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey] description];
}
That key is only in the launch options when the user starts your app from the notification (e.g. taps on it in notification center). Incidentally, I don't think a remote notification would be the class you're using (UILocalNotification).
If your app wasn't in the foreground when the device received the push, and the user didn't launch your app from the notification, the notification is gone. You have to check your own servers to see if you missed anything.

iOS 5 banner push notification disappear, user tap on app icon to start the app

With iOS 5, push notifications can appear as banner and disappear after a few seconds.
I understand that didReceiveRemoteNotification will be called when user taps on the banner.
My question is, if the banner has disappeared and my user sees that there is a badge number on the app, they will tap on the app icon to start the app. Now if the app is running in the background, how do I check that the app is brought to foreground and there has been a notification, and do the necessary?
The purpose of my notification is basically to inform user there has been an update to the app content and encourage them to run the app to get the latest contents. My app only checks for latest contents at launch time and doesn't check for updates periodically.
This question is a bit old, but I'll pop what I've found in here anyway.
There are two methods you need to implement in your app delegate to check if your app was either launched from the remote notification (From when the app is not running on your device), or received the remote notification while running (in the background or foreground).
First is a method that is already in your App Delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
To check if this was launched from a remote notification, have some code similar to this:
// Check to see if launched from notification
if (launchOptions != nil)
{
NSDictionary* dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (dictionary != nil)
{
NSLog(#"Launched from push notification: %#", dictionary);
// DO SOMETHING HERE
}
}
The other method you will need to implement is specifically for the case that your application for when your application is running:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(#"Received notification: %#", userInfo);
}
How you handle the notification from there is up to you, but that's how your app knows about it!
In this second method, you can check the UIApplicationState of the passed application to find out if you were in the foreground or background.

Detect if app got focus due to UILocalNotification

I'm making an app that keeps track of some reminders that repeats with an user defined interval.
I've made it so when the alert displays, the action title says "Renew". When you click this, the app opens, and here I want to create the next reminder, but the problem is that I don't know if the app opens because the notification button was tapped or if the notification fired while the app was running.
Anyone got any ideas?
The 'correct' way to do this is to examine your NSApplication's applicationState property in the application:didReceiveRemoteNotification: method of your delegate.
From the documentation for handling local notifications:
iOS Note: In iOS, you can determine whether an application is launched
as a result of the user tapping the action button or whether the
notification was delivered to the already-running application by
examining the application state. In the delegate’s implementation of
the application:didReceiveRemoteNotification: or
application:didReceiveLocalNotification: method, get the value of the
applicationState property and evaluate it. If the value is
UIApplicationStateInactive, the user tapped the action button; if the
value is UIApplicationStateActive, the application was frontmost when
it received the notification.
This is similar to your solution using flags set in applicationWillEnterForeground and applicationDidBecomeActive but with system support.
I don't know if my question was unclear but it seems that I got 4 different answers that all misinterpreted my question :P
However, I discovered that the didReceiveLocalNotivication happens between willEnterForeground and didBecomeActive, so I did this to determine if the app was already open or not:
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
NSLog(#"Opened from notification? %#", wasInactive ? #"yes!" : #"no!");
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
wasInactive = YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
wasInactive = NO;
}
Look up the documentation for UIApplication launch option keys. The last parameter to your application:didFinishLaunchingWithOptions: delegate method contains the information you need.
Also, look at application:didReceiveLocalNotification.
You're looking for
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
or
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
Documentation
If your application is already running you'll get this delegate message on the app delegate
application:didReceiveLocalNotification:
If it wasn't running you'll have to use
application:didFinishLaunchingWithOptions:
You need to respond appropriately in both methods to cover all cases
UPDATED
To detect if the user activated the action button requires a little more complexity. We can tell that application:didFinishLaunchingWithOptions: will have the local notification as a launch option, but it's more difficult with the application:didReceiveLocalNotification:.
Since the application becomes active after the user taps the button, we have to defer until we see that message (or not). Set an NSTimer in application:didReceiveLocalNotification and cancel it in didBecomeActive. That means the user pressed the action button. If the timer isn't cancelled the user was inside the app when it fired.
In your app delegate in this method:
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
You have to examine the launchOptions looking at this key:
UIApplicationLaunchOptionsLocalNotificationKey
When you are already active this will be called:
- (void) application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification

Handling Push notification

I am working with push notification, when the application is opened/or in backgroung process then it is no problem for me to receive the push notification, the problem occurs when i quit my application, it is not calling my delegate. Why?
When an app is launched from a push notification, the code path is a little different. Instead of getting the -application:didReceiveRemoteNotification: message, your app delegate gets some extra information passed into its -application:didFinishLaunchingWithOptions:. You can get the notification dictionary out of the options one and hand it off to your regular push-notification handler, like this:
- (void)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)options
{
NSDictionary *pushDict = [options objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if(pushDict)
{
[self application:app didReceiveRemoteNotification:pushDict];
}
// etc.
}

How do I tell if my iPhone app is running when a Push Notification is received?

I am sending Push Notifications to my iPhone app, and I'd like a different set of instructions to execute depending on whether the app is already launched or not. I'm new to iPhone development, and while I suspect UIApplication or my project's AppDelegate class has the solution, I haven't found a good answer. Is there an easy way to check for this?
Here's the more appropriate way of handling active/inactive state of the app.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
// check for the app state
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
//the app is in the foreground, so here you do your stuff since the OS does not do it for you
//navigate the "aps" dictionary looking for "loc-args" and "loc-key", for example, or your personal payload)
}
application.applicationIconBadgeNumber = 0;
}
didReceiveRemoteNotification: is called when the app is running, yes, but when it is suspended, the iOS takes care of putting up the badge, etc. If the app is in the foreground, the OS does nothing, and just calls your didReceiveRemoteNotification:.
Depending upon what you mean by "launched", you are either looking for:
Kevin's answer above (differentiates between launched or not launched)
or this (differentiates between suspended or active, but already launched):
Use a flag that is set true when the application becomes active, and false when the application is not active.
Flag (in header file [.h]):
BOOL applicationIsActive;
Code (in implementation file [.m]):
- (void)applicationDidBecomeActive:(UIApplication *)application {
applicationIsActive = YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
applicationIsActive = NO;
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if (applicationIsActive) {
// Handle notification in app active state here
}
else {
// Handle notification in app suspended state here
}
This works because when the application is suspended, the OS calls "applicationDidReceiveRemoteNotification" before it calls "applicationDidBecomeActive" during the "wake-up" process.
The "complete" answer is actually Kevin's answer plus this answer.
Hope this helps.
The UIApplication delegate has the method
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
which you need to implement. This receives the notification when the app is running.
If your app is not currently running and a notification is received then your app can be launched with
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
with the notification details held in the launchOptions dictionary. if the dictionary is nil then the user tapped the application icon as normal.
If you are going to check applicationState on iOS less than 4, you'll need to check that applicationState is supported:
if ([application respondsToSelector:#selector(applicationState)] ){
// Safe to check applicationState
UIApplicationState state = [application applicationState];
}
The Apple documentation for push notifications explains this:
However, there are two situations where applicationDidFinishLaunching: is not a suitable implementation site:
The application is running when the notification arrives.
The notification payload contains custom data that the application can use.
In the first case, where the application is running when iPhone OS receives a remote notification, you should implement the application:didReceiveRemoteNotification: method of UIApplicationDelegate if you want to download the data immediately. After downloading, be sure to remove the badge from the application icon. (If your application frequently checks with its provider for new data, implementing this method might not be necessary.)
This means that if your application:didReceiveRemoteNotification: delegate method is called, your app is running.