How to pause timer from appdelegate in xcode and objective c - objective-c

I am making a game for iPhone and want to be able to pause a timer when a user's game is interrupted like when they hit the home button. I know that in the app delegate there is a method when the app leaves the foreground called:
- (void)applicationWillResignActive:(UIApplication *)application
What I am struggling with is how to pause the timer. I have a function in my view controller that's called pauseGame and is used for when the user wants to pause the game. I was thinking that it would be easiest to pause the game by using this method. I cannot however understand how to call this method. Any ideas? And sorry for the beginner question.

The shortest way is to Use Notifications:
1. define a custom notification, at your application delegate (or anywhere else...)
#define kApplicationWillResignActiveNotification
#"kApplicationWillResignActiveNotification"
2. dispatch the notification when the applicationWillResignActive: method is called
[[NSNotificationCenter defaultCenter] postNotificationName:
kApplicationWillResignActive object:nil];
3. listen to that notification where ever you want in your project (* import the header file where you #defined the notification)
[[NSNotificationCenter defaultCenter] addObserver:self
selector: #selector(appResigned:)
name:kApplicationWillResignActiveNotification object: nil];
4. you can get the NSNotification Object if you add it to your selector
-(void)appResigned:(NSNotification *)notification;

Related

viewDidAppear equivalent in app delegate

I want to check orientation of app in the app delegate, is there a viewDidAppear equivalent in the app delegate?
Or where should I place the code to check where the orientation has changed (in the app delegate)
Well you have applicationDidFinishLoading:withOptions: which is your closest thing to a viewDidLoad, but it only runs once when the application first launches and that's it.
If you want to monitor the device orientation outside of a view controller, your best bet it to use the notification center, and register your class as an observer. Something like this should do the trick
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
Then whenever the orientation is changed, the orientationChanged: method will be called.
Just make sure that you unsubscribe when the class is destroyed or deallocated with
[[NSNotificationCenter defaultCenter] removeObserver:self];

Load Title ViewController When applicationDidBecomeActive:

I've created an app that has two viewcontrollers. The app opens to a title screen (general UIViewController titled 'Title') with a segue connection to the second view that is a custom class (OSViewController titled 'MapView'). As it is, the app suspends when entered into the background state so it opens right where you left off which is typically in MapView.
I want to know what I need to do to have the app start at the title screen when it becomes active. Preferably, I'd like it to open to the title screen if it is inactive for more than 1 minute. From what I've been reading, it seems like I would make a call in applicationDidBecomeActive: method in my AppDelegate to code this in. Please provide me the code to put in the applicationDidBecomeActive: method (if that's the right place to put it) that will reopen my app to the title screen when transitioning from the inactive state to the active state. My app is almost finished but I'd like to fix this issue and I don't have a lot of experience dealing with app states. Thanks in advance for your time.
If you need more information just ask.
You can also register a class as an observer of the "didBecomeActive" notification. You should place this in the viewDidLoad or the init method of your class.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(willBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
In this case, willBecomeActive: is a method that you have defined in your class that get's called when the app becomes active again. That might look something like this:
- (void)willBecomeActive:(NSNotification *)notification {
if (self.navigationController.topViewController == self) {
[self.navigationController popToRootViewControllerAnimated:YES];
}
}
You'll also need to add this in your viewDidUnload method
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
EDIT:
Thanks #AMayes for the advice. I don't believe key/value observing is necessary in this instance.

Execute code when app reopens

I have a Single View Application. When I hit the home button and ‘minimise’ the application I want to be able to execute code when the user reopens it.
For some reason viewDidAppear and viewWillAppear do not execute when I minimise and reopen the application.
Any suggestions?
Thanks in advance
sAdam
You can either execute code in the app delegate in
- (void)applicationDidBecomeActive:(UIApplication *)application
or register to observe the UIApplicationDidBecomeActiveNotification notification and execute your code in response.
There is also the notification UIApplicationWillEnterForegroundNotification and the method - (void)applicationWillEnterForeground:(UIApplication *)application in the app delegate.
To hook up notifications add this at an appropriate point
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(didBecomeActive:)
name:UIApplicationDidBecomeActiveNotification
object:nil];
Define a the corresponding method
- (void)didBecomeActive:(NSNotification *)notification;
{
// Do some stuff
}
Then don't forget to remove yourself an observer at an appropriate point
[[NSNotificationCenter defaultCenter] removeObserver:self];
Discussion
You most likely only want your viewController to respond to events whilst it is the currently active view controller so a good place to register for the notifications would be viewDidLoad and then a good place to remove yourself as an observer would be viewDidUnload
If you are wanting to run the same logic that occurs in your viewDidAppear: method then abstract it into another method and have viewDidAppear: and the method that responds to the notification call this new method.
This is because since Apple implemented "Multitasking", apps are completely reloaded when you start them again, just as if you had never closed them. Because of this, there is no reason for viewDidAppear to be called.
You could either implement
- (void)applicationWillEnterForeground:(UIApplication *)application
and do there what ever you want. Or you register for the notification UIApplicationWillEnterForegroundNotification in your view controller. Do this in viewDidLoad:
[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(myAppWillEnterForeground)
name:UIApplicationWillEnterForegroundNotification object:nil];
And of course implement the specified selector and do there what you want.
I am not sure how the answer by #Paul.s performs the OP request since registering UIApplicationDidBecomeActiveNotification will be executed twice:
When launching the app
When application goes into the background
A better practice will be to decouple those events into 2 different notifications:
UIApplicationDidBecomeActiveNotification:
Posted when the app becomes active.
An app is active when it is receiving events. An active app can be said to have focus. It gains focus after being launched, loses focus when an overlay window pops up or when the device is locked, and gains focus when the device is unlocked.
Which basically means that all logic related to "when application launched for the first time"
UIApplicationWillEnterForegroundNotification:
Posted shortly before an app leaves the background state on its way to becoming the active app.
Conclusion
This way we can create a design that will perform both algorithms but as a decoupled way:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(yourMethodName1) name:UIApplicationWillEnterForegroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(yourMethodName2) name:UIApplicationDidBecomeActiveNotification object:nil];
This because you don't redraw your view. Use applicationWillEnterForeground in the AppDelegate instead. This should work fine for you.

Stop CLLocationManager when user stops app using Fast App Switcher

I am developing an iOS Application which uses CLLocationManager to get GPS Data.
What's a proper way to stop CLLocationManager when the user presses the home button and then kills the app using fast app switcher?
How can I stop the CLLocationManager then to stop polling for GPS data? Does anybody knows a good way to achieve this, cause normally I can't execute any code when the user kills the application...
EDIT:
When I am sending the application to background, it should still get significantLocationChanges, so I can't stop CLLocationManager when the application is sent to the background!
In the AppDelegate there is a method called applicationWillResignActive. This method runs when your app is about to be sent to the background. If you have access to the CLLocationManager from your AppDelegate you can stop it right there. Otherwise you can post a Notification from applicationWillResignActive and whatever class has your CLLocationManager can subscribe to that Notification and handle it from there.
Post a Notification like this:
[[NSNotificationCenter defaultCenter] postNotificationName:#"appWillResignActive" object:nil];
And subscribe like this:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handleResign:) name:#"appWillResignActive" object:nil];
Then some method like this:
- (void)handleResign: (NSNotification *)notification
{
// stop CLLocationManager
}
EDIT:
If you want to run code when the app is being killed then you can run that code in this method in the AppDelegate:
- (void)applicationWillTerminate:(UIApplication *)application

Calling a method when the application is called from background

In applications like Foursquare when I click the Home button the application goes to background. Then when I click on its icon, it loads back the content on the screen.
When I send my app to background and then I recall it back, it doesn't load back the content to the screen. I have entered my code in the viewDidAppear method but it is not executed.
How is it possible to load the application content when it becomes active?
You need to respond to - (void)applicationDidBecomeActive:(UIApplication *)application or - (void)applicationWillEnterForeground:(UIApplication *)application or the equivalent UIApplication notifications. The UIViewController lifecycle calls like viewDidAppear aren't triggered by app lifecycle transitions.
smparkes suggestion is right. You could register for UIApplicationDidBecomeActiveNotification or UIApplicationWillEnterForegroundNotification. These notifications are called after those method (the ones smparkes wrote) are called. In the handler for this notification do what you want. For example in viewDidLoad for your controller register the following notification:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(doUpdate:)
name:UIApplicationDidBecomeActiveNotification object:nil];
Do not forget to remove in dealloc:
[[NSNotificationCenter defaultCenter] removeObserver:self];
Finally, doUpdate method could be the following
-(void)doUpdate:(NSNotification*)note
{
// do your stuff here...
}
I suggest you to read UIApplicationDelegate class reference. In particular read about Monitoring Application State Changes.
Hope it helps.
Suppose you want to listen to UIApplicationDidBecomeActiveNotification,here is the ObjC code that might help you.
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification
object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
// custom code goes here.
}];