as the title suggests, i am trying to stop my NSTimer when my game goes to background and start it back when the game starts again. the interruptions obviously could be such as receiving a phone call etc..
i am using the following code in app delegate to stop and restart the scene when the app gets interrupted, but it does not stop the timer.
- (void)applicationWillResignActive:(UIApplication *)application {
SKView *view = (SKView *)self.window.rootViewController.view;
view.scene.paused = YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
SKView *view = (SKView *)self.window.rootViewController.view;
view.scene.paused = NO;
}
in my scene where i place the timer, i have placed the observers in -(id)initWithSize:(CGSize)size
method. here are the observers:
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(goBackground)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(backBackground)
name:UIApplicationDidBecomeActiveNotification object:nil];
and the selector methods:
- (void) goBackground {
[timer invalidate], timer = nil;
}
- (void) backBackground {
if([timer isValid]) {
[timer invalidate];
}
timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateCounter:) userInfo:nil repeats:YES];
}
and i am also trying to deallocating the observers as follows:
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
}
the code above gets fired, i have placed an NSLog on all the above methods. but what happens is, it works for scene 1 which is the place for level 1 and when the player wins level 1 and goes to level two and i recreate the app interruption scenario again, it comes back and works for a few seconds before the game crashes.
obviously my code is not working and i have tried every which way i know how to get around that, but to no avail. the timer i have is just to show how much time is left in the level and has nothing to do with the win/lose scenario.(this maybe a bit of extra info which may not be needed to know).
is there anyway that i can stop and restart my timer when my game goes to background? i truly appreciate any help.
i don't know if the timer code is needed but it is as follows:
- (void) gameTimerLabel {
gameTimerLabel = [SKLabelNode labelNodeWithFontNamed:@"ArialRoundedMTBold"];
// gameTimerLabel.text = [NSString stringWithFormat:@"%d", _lives];
gameTimerLabel.fontSize = 20.0;
gameTimerLabel.fontColor = [SKColor colorWithRed:135.0/255 green:207.0/255 blue:232.0/255 alpha:0.6];
gameTimerLabel.position = gameTimerLabel.position = CGPointMake(270, 282);
[self addChild:gameTimerLabel];
}
- (void)updateCounter:(NSTimer *)theTimer {
if(secondsLeft > 0 ){
secondsLeft -- ;
//hours = secondsLeft / 3600;
minutes = (secondsLeft % 3600) / 60;
seconds = (secondsLeft %3600) % 60;
gameTimerLabel.text = [NSString stringWithFormat:@"%02d:%02d", minutes, seconds];
}
else{
secondsLeft = 70;
}
}
-(void)countdownTimer{
secondsLeft = hours = minutes = seconds = 0;
if([timer isValid]) {
[timer invalidate];
}
timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateCounter:) userInfo:nil repeats:YES];
}
it is basically just a count down timer nothing fancy.
Edit:
Ben-G, was right. there is almost no way to manage NSTimer in background/foreground, so i used the SKAction approach and did get the job done. for those who are interested, here is the working code:
@implementation MyScene {
SKLabelNode *gameTimerLabel;
int countDownInt;
int secondsLeft;
}
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
secondsLeft = 70;
[self gameTimerLabel];
}
return self;
}
- (void) gameTimerLabel {
gameTimerLabel = [SKLabelNode labelNodeWithFontNamed:@"ArialRoundedMTBold"];
gameTimerLabel.fontSize = 20.0;
gameTimerLabel.fontColor = [SKColor colorWithRed:135.0/255 green:207.0/255 blue:232.0/255 alpha:0.6];
gameTimerLabel.position = gameTimerLabel.position = CGPointMake(270, 282);
[self addChild:gameTimerLabel];
countDownInt = secondsLeft;
SKAction *updateLabel = [SKAction runBlock:^{
gameTimerLabel.text = [NSString stringWithFormat:@" %02d", countDownInt];
--countDownInt;
}];
SKAction *wait = [SKAction waitForDuration:1.0];
SKAction *updateLabelAndWait = [SKAction sequence:@[updateLabel, wait]];
[self runAction:[SKAction repeatAction:updateLabelAndWait count:secondsLeft] completion:^{
gameTimerLabel.text = @"Time's Up";
}];
}
thats all. thanks again to Ben-G for pointing me in the right direction.