I'm working on match 3 game in there I need to add lives. If user didn't solve puzzle he loses 1 life. I made it but how I can make lives refill every 20 minutes? I'm stuck. Another on problem is if game moves to background, how to check after user open game again?
My game is Sprite Kit project on objective-c
First part of your question:
You are looking for some timer. You could use NSTimer to call a method every 20m or SKAction with waitForDuration method init.
Second part of your question:
In your AppDelegate find or add method applicationWillEnterForeground:(UIApplication *)application
. This method is called everytime your app should become active. Or addObserver for applicationWillEnterForeground notification where you need it.
Related
I'm doing an alarm application with repeat interval. My problem is that even if the user clicks the local notification, returns to the app, and then goes back to the home screen of the phone the UILocalNotification stills fire every minute. I'm aware of [[UIApplication sharedApplication] cancelAllLocalNotifications]; and I put it in the my viewDidLoad method. Any advice how I can fix this?
Putting it in viewDidLoad is good for some circumstances just not yours. Think about when viewDidLoad is called:
Called after the controller's view is loaded into memory.
So in other words, the next time it gets called is after your little ARC friend deallocates it from memory. So, yes, eventually cancelAllLocalNotifications will get called again, just not when a user puts the app in the background and then returns it to foreground, because its still has a home in memory; it will be called next time that particular view gets loaded into the memory.
Additionally, that probably is not good logic, because that will happen for every user, even if they didn't want to cancel the repeats.
Ultimately, you will have to create additional logic to decipher which users have, say, hit 'snooze' or 'cancel' with whatever resource works for you and your project. Personally, I would guide you towards using a category based notification, that way you cancel it as needed, instead of 'just in case'. See here how to set those up.
In my GameScene.m I have a method called wentToBackGround. This method is called by applicationWillResignActive in AppDelegate:
GameScene *gameScene = [[GameScene alloc]init];
[gameScene wentToBackground];
In wentToBackGround I move my player sprite (just to test if it works) like so:
-(void)wentToBackground {
NSLog(#"BG");
self.player.position = CGPointMake(CGRectGetMidX(self.frame), 1000);
}
The NSLog works, however the players position remains the same. Is this due to the fact that SpriteKit automatically pauses everything once it enters the BG. How do I work around this. I eventually want there to be a pause menu that opens as soon as the user leaves the app. How do I do this properly?
I think it also might not work, because I made a new instance of the GameScene. How do I use the old instance? (the old instance was created in another scene, the TitleScene)
I think it also might not work, because I made a new instance of the GameScene
Correct, you got it! Well done. Keep in mind (and I think you are now grasping this) that a class is just a template. The objects in your app are instances, and you can make many instances of one class. So when you say
[[GameScene alloc]init]
you are making a new instance. That's legal but pointless; sending it the wentToBackground message does nothing of any use, because it isn't in your interface. The GameScene instance you want to talk to, the one in your interface, is elsewhere.
Getting a reference to a particular existing instance can be tricky. You sometimes have to arrange things in advance to make it possible. However, I think you can avoid the whole problem here. UIApplication has not only an app delegate method but also a notification for letting you know that you will resign active. So just have the GameScene register for that notification, and now you don't have to involve the app delegate at all.
Here's the documentation on that notification:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/#//apple_ref/c/data/UIApplicationWillResignActiveNotification
Any object can register for a notification, so this is a way to establish that your GameScene wants to be informed of deactivation.
I got a class which runs a bunch of timers, and when the app enters background I want to stop them. I know of course this is done in the appDelegate but when I got the timer class initialized as an instance variable in another class.. What´s the common ways of getting hold of the instance object in the appDelegate?
Do I delegate the didEnterBackground to the class with the timer i want to stop?
Do I make the timer a singelton?
Use the notification center?
or, hopefully there are better ways than this!
Probably the easiest thing to do here is post a notification when your app delegate gets the "didEnterBackground:" call. And have your timer class (or class that has a bunch of timers) listening for that notification.
You'd need an matching app-delegate-does-a-post method if you want to restart the timers when the app comes back to the fireground.
You're right - the only method you will need is didEnterBackground method in your appDelegate.
Using notification center may cause you a lot of problem (you 100% positive that every time app enter backgound you will have timers fire in your class?). Notification Center in this case can easily cause crash.
Here is what i will do:
Set up my timers in one class (let's call it TimerManager)
Make my class a Singleton class.
In TimerManager i will create array/set with timers.
Call singleton class right after my first ViewControllers will load (or in AppDelegate). Basically right after my app will start.
Add Timers to my Set/Array when i need it.
Create a method stopAllTimers
\
-(void)stopAllTimers {
for(NSTimer *timer in self.allTimers) {
[timer invalidate];
}
}
Call this method in my didEnterBacground : [[TimerManager sharedInstance] stopAllTimers]
That's it and this is perfectly safe.
I am currently developing an app that will need to terminate after running in the background for more than five minutes. In order to do this, I will have to have a timer running in the background after the the Home button has been pressed or in case of an interruptions such as an SMS or a telephone call, then, after five minutes the applicationWillTerminate method will be called. My first question is should I put the applicationWillTerminate in the applicationWillResignActive method or in the applicationDidEnterBackground method? My second question is since this is an app with more that one view, Should I write these things in the AppDelegate class or elsewhere? Thank you for your response.
1) You can't force your app to finish programatically.
2) You should never call these AppDelegate methods by yourself. They're meant to be called only by the system.
Reference: UIApplicationDelegate Protocol Reference.
This is pretty ghetto, but what you can do is make your app crash when you want it to exit, and it will close automatically, granted that's not closing the app, but there's no real harm in it as long as you are in control of how it crashes try to go for a bad access error, aka trying to access something that has been deallocated
as for running a timer in the background, i don't know per say if you can do that, but as an alternative you can save the time when they leave the app aka the app goes into the background and then you can have all the events return to your app of the view controller that is first responder, and each UIEvent has a time stamp, and regardless of which event it is you can compare the time stamps and see if it's greater than 5 minutes
Regardless i don't suggest any of the above, but that is the best answer i can come up with for your question
the code for receiving events out side of your app
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
will start the event tracking and the call back is:
- (void)remoteControlReceivedWithEvent:(UIEvent *)event { }
but you have to remember to
[self becomeFirstResponder];
this tells the device which view controller to go to for the event tracking, oh and don't forget to resign first responder, and endReceivingRemotecontrolEvents
I'm building a game for iOS using Cocos2D. In my game I have a pause menu that can be pulled up when playing the game. A simple tap will return from the pause menu to the game. What I would like to implement is a clean way to resume the game on the pause menu if the method applicationDidBecomeActive is called. The problem is that only the appDelegate receives the call to applicationDidBecomeActive, and my pause menu is many layers deeper than that. Right now I'm essentially passing the applicationDidBecomeActive call through about 4 different layers to get it down to the pause menu. There must be a cleaner way?
Sure is. Just add an observer for the UIApplicationDidBecomeActiveNotification from anywhere that's convenient. Application state changes can be hooked that way as well as via the app's delegate.
(Docs here.)
Read about the NSNotificationCenter
here and at Apple or just receive the UIApplicationDidBecomeActiveNotification anywhere.
take a BOOL variable in appdelegate.h with property and synthesised it then when pause button pressed from any scene set this variable to yes.
in applicationDidBecomeActive method of appdelegate check if(self.pause == YES) then don't resume ccdirector else resume it
i used this in my game and it work fine when i press pause and then press home button and when come back the app is still pause. try this