Piling up UILocalNotifications - iphone

I'm developping an app that sends tips to users every five minutes through UILocalNotifications. The problem is that if you don't use your phone for a while, the notifications pile up and when you unlock the phone, you have to dismiss them one after the other, which can become quite annoying if you haven't used the phone for quite a while. Clicking the action button on the Alert sends you back to the application but even then, you still have to go through all the notifications.
Is there any means of dismissing all the notifications that have already been fired with a single click ?
Thanks for your help.
Miky Mike

Well, actually, I realize I made a mistake.
In order to cancel all the UIlocalNotifications at one, I just have to create this simple method : one line of code is enough :
- (void)application:(UIApplication *)app didReceiveLocalNotification :(UILocalNotification *)notification {
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
and there you are. Thanks anyway.

Before scheduling the next alarm you better to cancel all the previous notifications and then set the new one,
UIApplication* app = [UIApplication sharedApplication];
NSArray* oldNotifications = [app scheduledLocalNotifications];
// Clear out the old notification before scheduling a new one.
if ([oldNotifications count] > 0)
[app cancelAllLocalNotifications];

Related

Local Notification (repeat) fired after new install of app

in my app I am using local notifications and often they have a repeat interval set.
The problem is, when the user deletes the app and reinstalls it, the repeat notifications start firing again.
Is there a fix for this problem? Will the following suggestion from another user work? :
you can use [[UIApplication sharedApplication] cancelAllLocalNotifications]; only at first launch, so that "old" notification will be cancelled....(I haven't tried that)
Thanks a lot!
you can use [[UIApplication sharedApplication]
cancelAllLocalNotifications]; only at first launch, so that "old"
notification will be cancelled...
This is not your solution. This will cancel all your already scheduled notification every time when your didFinishLaunching method will called. So before applying above solution there should be one more check. Store a value in NSUserDefauls for checking that you are installing application again after deleting.
if(![[NSUserDefaults standardUserDefaults]objectForKey:#"Notification"]){
[[UIApplication sharedApplication] cancelAllLocalNotifications]
[[NSUserDefaults standardUserDefaults]setBool:Yes ForKey:#"Notification"];
}
This will prevent from canceling all notifications every time.

How to know if a task is executing in background

In my app I'm downloading lots of images on a method.
I'm using a
downloadTask = [[UIApplication sharedApplication]
beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:downloadTask];
downloadTask = UIBackgroundTaskInvalid;
}];
This is working fine, if I press the home or sleep button, the images continue downloading.
I'm showing the progress in a UIProgressView inside an UIAlertView, and when the percent is 100% the alertView is dissmised and I change the viewController to other where I show the donwloaded images.
But I only want this to happen if the app is really active at the moment the download finish.
I have been looking at the app state and while it's downloading with the screen off.
[UIApplication sharedApplication].applicationState
the state is UIApplicationStateActive during all the donwload
How can I can know if the downloading is happening with the screen off or on?
EDITED AFTER ACCEPTING THE ANSWER:
I just discovered, if I tap the home button, the app enters in UIApplicationStateBackground, if I tap the wake/sleep it enters in UIApplicationStateInactive
Following the approach of the correct answer, my app contines donwloading in both cases.
The screen is off in two states (apart from when the app has not been even opened):
suspended : in this case you don't have to worry because the download won't procede until the app gets active again; It will enter this state on
background : it's in this state for a limited amount of time before going in suspend, and the screen is already off in this moment. Here you may want to check then whether to do all the things you said or not, because in this state code can be still executed. In this state the app status is UIApplicationStateBackground, so you could just perform a check like this:
You probably want to check whether the app is in background execution in order to achieve the result. Just like this:
if([[UIApplication sharedApplication] applicationState] != UIApplicationStateBackground) {
// Do stuff
}
If it's in background, so the screen is off.
UPDATE: after few test, what I figured out is that the behaviour you are expieriencing is probably due to the execution of the download on the main thread.
You should send the download on (for instance) the global queue. This way the application will enter the background state as expected:
....
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:self.bti];
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self doBackgroundStuff];
});
....
This way, if the app is put on background while the download is in progress, the application state will turn into UIApplicationStateBackground, and then you can check it as I wrote initially. If you are doing UI updates during the progress remember to send them back to the main thread (because the download is now on a different one).
You can check whether your app is running in the background or not by setting a flag in the designated application delegate methodsapplicationDidEnterBackground: and applicationWillEnterForeground:. Example:
- (void)applicationDidEnterBackground:(UIApplication *)application
_applicationRunsInForeground = NO;
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
_applicationRunsInForeground = YES;
}
If you don't want to have this _applicationRunsInForeground flag inside your application delegate, you could observe the delegate's NSNotifications in your viewcontroller class instead (UIApplicationWillEnterForegroundNotification and UIApplicationDidEnterBackgroundNotification).

UILocalNotification - The right way to finish/wrap up a local notification after notification is received

In the application, I have received the local notification and taken the appropriate actions - so far so good. But after that, what's the appropriate actions to take to "clean up" the local notification object?
I haven't found any direct instruction on this in my search of Apple/StackOverflow, so I assume it's just discarded by iOS and as long as I release any related the object/properties then I should be good to go.
But am I missing anything? Do i have to cancel it from UIApplication? I wouldn't want for these just to be accumulating in the scheduledLocalNotifications array, for example.
Thanks.
Once the user actually receives the notification thats it, its gone from the schedule and you dont have to do anything to clean up the notification, if you have scheduled local notications (that have not fired) and want to clean those up you can do something like
UIApplication* app = [UIApplication sharedApplication];
NSArray* oldNotifications = [app scheduledLocalNotifications];
// Clear out the old notification before scheduling a new one.
if ([oldNotifications count] > 0)
[app cancelAllLocalNotifications];
Hope it helps

badge number count increament

I have implemented the local notification concept, it is working properly but there is a problem in badge number it is not increamenting automatically as notifications occurs. I have got a link where solution for this problem is given but don't know how to use it in app delegate. Following is the link... If someone know how to auto increament the badge number ,please provide me some solution.
https://github.com/csheldrick/UILocalNotification
Thanku very much.
When you create your local notification then before registring it with the system add this line of code.
localNotif.applicationIconBadgeNumber = [UIApplication sharedApplication].applicationIconBadgeNumber+ 1;
and then you register you notification with the system
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
localNotif is object of UILocalNotification
Hope this helps
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
[UIApplication sharedApplication].applicationIconBadgeNumber=application.applicationIconBadgeNumber+1;
}
i hope it will help ful to you

Schedule a local notification on firing a local notification

I want to schedule a local notification when my previous local notification gets fired.
It should get scheduled disregarding the user taps 'View' or 'Cancel'.I am not getting proper place(delegate method)to schedule a new notification.According to Apple docs,application:(UIApplication *)application didFinishLaunchingWithOptions: can be used but it doesn't seems to be get called when application comes to foreground from background and application:(UIApplication *)application didReceiveLocalNotification: gets called only on click of 'View' and not on close.How should I do this?Any help is highly appreciated.
Yes. You are correct about the local notifications. You should click "view" to get the didReceiveLocalNotification: triggered. If you click "Cancel", you are not caring about the notificaiton. If you don't care, why should the iOS care? :-)
You are scheduling the notification. So, you know when it will be fired. Don't you? Then why wait for the first notification to be fired? Just schedule the second notification along with the first notification.
A workaround:
Local and Push Notification Programming Guide
says that only 64 local notifications are allowed per app. So, schedule the first 64 notifications initially. And when the app opens the next time, check [UIApplication sharedApplication] scheduledLocalNotifications], and schedule the next (64 - scheduledLocalNotifications) notifications.
int scheduledNotifications = [UIApplication sharedApplication] scheduledLocalNotifications];
int n = 64 - scheduledNotifications;
[self Schedule-next-n-notifications];
Note: We can't guarantee that this will work perfectly. In case, if the app opens after very long gap, for example after 1 or 2 months, some notifications would have not been scheduled at the proper time.