Cancel all local notifications when app is closed by the user - objective-c

There is a small bug in my App.
My App displays notifications at specific times when the App is running and cancel all of them whenever a button is switched.
My problem is that whenever a user closes the App using the multitasking feature of iOS the notifications are still showing up.
I tried to add the following code which doesn't work:
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
The problem is that my App should show notifications when the App is running but shouldn't show notifications when the App is terminated.
Why does the above code not work?

The correct answer is that this cannot currently be done by a multitasking app. One solution is to set a flag in our info.plist declaring your app wants to be killed when the user switches to another app - then you will get the willTerminate message (but get killed then).
There are huge numbers of threads on this topic, one which quotes an Apple doc that tells you backgrounded apps that are terminated do NOT get the willTerminate message is here.
For me, this just means I can now close an open bugreport out with a 'cannot fix' resolution :-)

Just because your app is visible in the app-changer, it doesn't mean it is still running.. it can get closed at any point. You cannot differentiate between the OS closing your app or the user closing your app.
Perhaps a button would be the solution? A button that cancels all notifications?
Or you run a real background task (which can last for about 5 minutes) and stop all notifications afterwards. Or you just schedule the notifications for the next 5-10 minutes and that's it.
For what are you using them?

Related

iOS 7 - Update Data Every 24 Hours

I'm creating an app that needs to check for data once a day (midnight). I know there is a background fetch mode in iOS7, but from what I know there is no way to force it to update in given time interval. Is there any way to do this and still pass the Appstore review?
Thank you for any suggestions.
There is not real way to do this, since it requires you app to be running in background. background running modes are restricted to audio, VOIP, location and accessory type apps.
What you could do is just check when you last update data in the app when the user launches the app. This way you will only update data when the user starts your app and also only use data when the user is really using the app.
The background fetching will only work if the user is start your app often and iOS will allow you app to do background fetching. iOS will decide when you app is allowed to do a background refresh and you have little influence over the interval.
UIApplicationBackgroundFetchIntervalMinimum
The smallest fetchinterval supported by the system.
Maybe it's not exactly answer you expect but in iOS 7 there is a functionality which allow you to fetch the data every some period of time.
In this scenario iOS intelligently schedules the background fetch events based on your app usage and it helps you save battery life. So this not going to work every 24h but I think you can read the data and if it has been updated refresh the app if not ignore it.
In your Xcode 5 -> Target -> Capabilities turn on Background modes (background fetch).
And in application:didFinishLaunchingWithOptions add:
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
This is a method which will be called:
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
}

registerForRemoteNotificationTypes slows my app! Can i execute it only first time?

I added push notification to my app, and i execute in the appdelegate the registerForRemoteNotificationTypes in order to ask the user to accept the push. The first time i open the app it ask if i want to receive push and all goes well, but the next times the execution of the registerForRemoteNotificationTypes make the app hang for some annoying seconds, slowing too much the app.
There's a way not to execute the registerForRemoteNotificationTypes if the user already answered the question about activating or not the push notification? (I'm working in ios 6.1)

Alternatives to applicationDidEnterBackground and applicationWillResignActive?

I've got an app that changes the screen brightness with [UIScreen mainScreen].brightness = newBrightness, and I want to restore the brightness to it's previous state when the user finishes using it.
I've tried these two delegate methods:
- (void)applicationDidEnterBackground:(UIApplication *)application
- (void)applicationWillResignActive:(UIApplication *)application
But without much success. I suspect my app must be in the foreground to change the brightness? When I change the brightness in didEnterBackgroundMethod, it has no effect at all. When I use willResignActive it does restore the brightness if I switch to another app, but it has no effect when I press the home button.
Are there any notifications or delegate methods that are executed before the app leaves the foreground?
It seems this happens to others as well: see this S.O. post.
Only way around it seems to be forgetting about setBrightness and simulating it by overlaying a black-semi-transparent on your view...
OLD ANSWER:
willResignActive should also be called when you press the home button before the application enters the background state.
This method is called to let your application know that it is about to move from the active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. An application in the inactive state continues to run but does not dispatch incoming events to responders.
This is also the behavior I witness. So, my guess (but it's just a guess) is that your app is not set to support background, so that when pressing the home button it is terminated. In this case applicationDidEnterBackground is not called.
I would suggest to check the info.plist file in your project for the UIApplicationExitsOnSuspend or "Select Application does not run in background" key.
Furthermore, you could try and put some breakpoints (or NSLog traces) in those functions and check whether they are effectively called as expected.
According to Apple´s DevForum it seems to be a bug that Apple don´t want to fix soon.

iPad crash after fast restart, when performing task at exit

I'm working on an iPad app, targeting iOS 3.2 (so everyone can run it), and when the user presses the Home button, the app gets an applicationWillTerminate: message and it sends usage data to a server before it exits.
This all works fine. But if you exit and then restart the app before it's done exiting, it appears to crash.
The 5 seconds you get to clean up when the app is exiting begins once you get the applicationWillTerminate: message, but the app disappears immediately from the device, giving the user the opportunity to launch it again.
I think what's happening, is that they're just reactivating the app before it's done exiting, and so they're just jumping back into the first instance of the app just before it actually exits. So the second instance of the app appears to be crashing.
There is no crash log, and putting a log message into the application:didFinishLaunchingWithOptions: doesn't produce any logs in the console from that second launching of the app. This is why I'm pretty sure it's not actually creating a second instance but just re-entering the first instance which is almost done exiting.
So are there any ideas out there about how to avoid this situation? It seems odd that you are given 5 seconds to perform actions on exit, but then this odd behaviour happens as a result.
I'm worried part of the problem is that the app is targeting iOS 3.2 and is actually exiting when the HOME button is pressed, and if it were just going into the background, this wouldn't be an issue. Sadly, changing that behaviour is just not an option at this moment.

Problem: restarting App

My App is a view-based application. At the beginning I show my logo and after a delay of a few seconds it changes into another view. from then on the user can switch to a lot of different views.
Sooooo.. My Problem: The thing is, when I restart my App. [..well closing and reopen by touching the icon..] the app itself doesnt restart in the sence of jumping to the very first view. to the contrary: at restart the user just returns to the last view that was open.
So I dont know why this is.
Is it normal to somehow manually tell the app to return to the very first view after restart? And if so, how do I have to do that?
PS.
I have so no idea what to do.. Maybe my problem has to do with the timer i used in the first view to change after a delay of time?
Please, is there anyone, who can help me?
Your problem is that, as of iPhone 4, returning to the home screen does not terminate your app. It's just made inactive, so opening it again reactivates it. In most cases, this is a good thing. If it doesn't work for your app, you can add the UIApplicationExitsOnSuspend key to your Info.plist with a value of YES.
(As I said, you should only do this if it really helps usability. If it's just about getting your splash screen shown again, most users and possibly Apple will frown upon it.)
iOS 4.0 and greater have a fast-start thing that allows apps to restart back from where they were upon restarting. There are several ways to deal with this:
1.) your App Delegate receives info about being but into the background and resumed. - (void)applicationDidBecomeActive:(UIApplication *)application and - (void)applicationDidEnterBackground:(UIApplication *)application are the relevant functions here. Check the docs.
2.) You can also disable the background, inactive state completely by including UIApplicationExitsOnSuspend in you Info.plist as Chuck already pointed out.
Overall, you should check the application state docs on Apple's Side.