Multiple simultaneous UILocalNotifications - iphone

If I have two (or more) UILcalNotifications that fire more or less on the same time and the application is active in the background, I found out that:
Two alerts are shown simultaneously to the user, one covering the other.
When the user touches "View" on the top alert, the alert is removed from the screen, didReceiveLocalNotification is called for this notification, and the application enters the foreground.
As soon as the top alert is removed from the screen (and the application is already in the foreground), the user sees the alert that was under it.
However, if the user touches "View" for this alert as well, nothing happens. didReceiveLocalNotification is not called for the second notification, and the application has no way of knowing that the user wanted to view this notification as well.
If the application happens to be in the foreground when the two notifications fire, there's no problem - didReceiveLocalNotification is called for both, one after the other (no alert is shown in this case).
Is there a way to get some notification for both "View" confirmations in the above case? Am I doing something wrong?

Actually the previous notification do not call the didReceiveNotification delegate method (or any other method if two or more notification pops while app in background). But you can track that previous notification as your need.
For example, if you have a app that send data to the server on clicking view of notification then on daily basis save the data into a plist (and edit it daily) that data has been sent or not by "Yes" or "No" so while a notification comes the app checks into the plist that the data for previous alarms have been sent or not. If no then it will send it at that time. So this is just an single way.

Alert view needs to have it's delegate set (typically to self) to receive events.

Related

NSNotificationCenter re-executes notifications

I am using NSNotificationCenter to set a variable shared when a notification comes in across 3 TableViewControllers (all subclassed from the same class).
All works fine except for the following scenario:
The user is in the main view (the view that actually processes/responds to notifications) when the app goes to the background (e.g. user presses Home button). If a notification comes in and the user launches the app either from the icon or from the alert the app behaves as if it needs to process not only the last notification but also all the notification up-to-now.
For example: let;'s assume that the app processed 5 notification already. The app moved to the background and then a notification came in. The user launches the app from the icon which causes the app to move to the foreground. The app will trigger 1 action per notification.
This is not the case if the user was in any other screen before the app moved to background. However, if the user moved to the main view, the notification was processed and the app moved to background again, on the next notification, the app will process 7 notifications (the 5 we had + 1 previous + 1 current).
While conceptually it seems as if my app is spawning n-observers, it is not clear to me why. I set an observer in the base class in viewWillAppear and remove in viewWillDisappear (also tried a deinit block - no change in behaviour).
Any idea why the observer accumulate all notifications? Is this the normal behaviour for an observer? If so, how do I remove 'observed and processed' messages?
The solution to my problem was to remove the observer before adding it.
The problem itself came down to the fact that the order of cleanup (i.e. add observer in viewWillAppear, remove observer viewWillDisappear) did not match my expectations. The result was that the observer was being added again and again but the corresponding 'remove' did not actually 'happen'.
I guess it was due to the fact that adding/removing observers took place in the base class (and not sub-class).

Notiication when user selects entry from notification center

When a user selects an entry from the push notification center, it triggers the
application:didReceiveRemoteNotification:
method on the application delegate. Is there a way to tell when a push notification is triggered while the user is in the app, and when they select an older push from their notification center?
Is there a way to tell when a push notification is triggered while the user is in the app[...]?
For this I always understood that
application:didReceiveRemoteNotification
is called for every notification received after you start up the app, even if it is on foreground. Although I haven't had the need to do this (and can't confirm it at the moment), so I am calling on theory only. But that's what I can understand from the following on Local and Push Notification Guide.
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.
has for
Is there a way to tell when [...](a user) select an older push from their notification center?
For this you could add a order(or time) variable to your push payload to be able to understand if the user is selecting/activating the app trough a push older that a previous one selected.
Check this page for more on adding extra data to the Push Notification.

How do i find out what state the application is in as the result of a notification?

I have a UILocalNotification set up, and as far as i can see it i have 5 different scenarios:
The app is not running, the user chooses to view the notification, so it launches the app.
The app is not running, the user chooses to close the notification, then opens the app at a later date.
The app is running in the background, the user chooses to view the notification, so it brings the app to the foreground.
The app is running in the background, the user chooses to close the notification, then opens the app bringing it to the foreground at a later date.
The app is running in the foreground.
How do i deal with these 5 different scenarios?
Put your code into application:didFinishLaunchingWithOptions:. In
the actions NSDictionary you will find the information about the
notification.
You can again check in application:didFinishLaunchingWithOptions: if the local
notification is still active and take appropriate action.
Put your code into applicationWillEnterForeground:
Again the same spot, just check if there are active local notifications.
Here you can check in application:didReceiveLocalNotification: and either notify the user or not.
Not exactly sure what you're after, but the following might answer your question.
From the documentation:
When the system delivers a local notification, several things can happen, depending on the application state and the type of notification. If the application is not frontmost and visible, the system displays the alert message, badges the application, and plays a sound—whatever is specified in the notification. If the notification is an alert and the user taps the action button (or, if the device is locked, drags open the action slider), the application is launched. In the application:didFinishLaunchingWithOptions: method the application delegate can obtain the UILocalNotification object from the passed-in options dictionary by using the UIApplicationLaunchOptionsLocalNotificationKey key. The delegate can inspect the properties of the notification and, if the notification includes custom data in its userInfo dictionary, it can access that data and process it accordingly. On the other hand, if the local notification only badges the application icon, and the user in response launches the application, the application:didFinishLaunchingWithOptions: method is invoked, but no UILocalNotification object is included in the options dictionary.
If the application is foremost and visible when the system delivers the notification, no alert is shown, no icon is badged, and no sound is played. However, the application:didReceiveLocalNotification: is called if the application delegate implements it. The UILocalNotification instance is passed into this method, and the delegate can check its properties or access any custom data from the userInfo dictionary.

Home button press , Which AppDelegate method should i use for scheduling a local notification

I would like to schedule a local notification as soon as the user hits the home button.
Which App delegate method should I use in this case :
applicationWillResignActive
applicationDidEnterBackground
applicationWillTerminate
Well I guess I shouldn't use the third one, but what is the difference between the first two ?
Is there any way to distinguish getting interrupted by a phone call/other notification and actually pressing the home button ?
Thanks in advance.
To schedule local notification you shold use applicationDidEnterBackground instead of using applicationWillResignActive because applicationWillResignActive call every time when app get some specific interruption line phone call, sms. You want to schedule notification when user press home button and in this case applicationDidEnterBackground is the appropriate place to do this.
One thing that should be remember before using applicationDidEnterBackground is that this delegate has approximately five seconds to perform any task, if any task in this delegate will take more time then os will terminate your app. You can also request for additional time for execution by using beginBackgroundTaskWithExpirationHandler and then use a secondary thread to perform a task. For more detail about application delegates follow the links -
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIApplicationDelegate_Protocol/Reference/Reference.html
http://www.cocoanetics.com/2010/07/understanding-ios-4-backgrounding-and-delegate-messaging/
You should use applicationDidEnterBackground.
applicationWillResignActive gets called anytime your app is interrupted such as a phone call or SMS message. In this case if the user ignores these then your app will keep running in the foreground.
applicationDidEnterBackground only gets called when your app actually goes to the background.
You should do this in applicationDidEnterBackground:
applicationWillTerminate will not be
called when the user hits the home
button. With app switching this is
only sent when the user explicitly
quits the app or possibly in low
memory situations.
applicationWillResignActive is
additionally called when the app is
briefly interrupted, say by an SMS or
phone call alert. (Though if the user
then switches to Messages or Phone
app your app will eventually get a
applicationDidEnterBackground
message).
So it sounds like you're specifically interested in the point when the user taps the home button and the app goes to the background. applicationDidEnterBackground is the place.
You could also always schedule the local notification and only respond to it if the app isn't running when it occurs. Not better necessarily, just an option to consider.

Deferentiating the push notification handler when application is foreground and background

It is said that (correct me if I'm wrong) if the application is in the foreground we have to handle push notifications in the "didReceiveRemoteNotification" and if the application is in the background using "didFinishLaunchingWithOptions" when user taps the "view" button of the app. As I dont have a phone to test I want to know whether I am handling this properly.
1) What will be invoked when I taps on the "View" button in the push notification?
2) Let say I am running the application in the foreground and push notification receives at the same time. Will I be given the push notification alert? If so what will happen if the user click on the View button?
3) In this thread How to handle push notifications if the application is already running? it says:
"alert" key will not be there directly under the userInfo dictionary, you need to get another dictionary with name "aps" and then get the "alert" or "body" from "aps" dictionary"
Is this true?
4) I need to push to a certain view when the user clicks on the View button. Hence do I need to handle that code in both methods?
Thank you
There's a nice rundown of the methods invoked by a push notification in this Apple vid: http://developer.apple.com/videos/iphone/#video-advanced-pushnotification - make sure you visit download the full version in iTunes.
This direct link might work: http://developer.apple.com/itunes/?destination=adc.apple.com.3391495696.03391495702.3416205190?i=1378617410
Either way, the general idea is that if your app isn't in the foreground, tapping your view button will trigger didFinishLaunchingWithOptions, and if it is the foreground app, you'll get the didReceiveRemoteNotification.
I don't think you'll get the alert. The method didReceiveRemoteNotification will be called, and it'll be up to you to show a UIAlert if you want.
Yes - that's true.
Yes, but I think you can simplify this by creating a third method specifically designed to handle your view. You can call this from both didFinishLaunching (only if it launched via a notification), and didReceiveRemoteNotification. This way, if your app needs to be launched, you can have time to do any other setup you might need to do for the app to work right out of the get-go (load saved data, init tabbar controllers or anything else like that).
Best of luck