使用UILocalNotification恢复游戏生活

时间:2015-05-27 22:00:31

标签: objective-c nsdate uilocalnotification

我正在Spritekit中创建一个游戏,我试图以一种方式设置我的游戏,当一个玩家失去所有生命时,他们必须等待30分钟才能恢复他们的生命,这样他们就可以再玩一次。我尝试使用NSTimer执行此操作,但我认为UINotification将更有效,因为无论应用程序是在后台终止,正在使用还是未使用,我都希望此计时器能够运行。我在设置时遇到了问题。

到目前为止,当用户到达GameOverScene

时,我已经编写了以下代码
 -(instancetype)initWithSize:(CGSize)size {
 if (GameLives < 5 ) {
alarm = [[UILocalNotification alloc] init];
      alarm.fireDate = [NSDate dateWithTimeIntervalSinceNow:thirtyNewMinutes];
      alarm.timeZone = [NSTimeZone localTimeZone];
      [[UIApplication sharedApplication]  scheduleLocalNotification:alarm];
      alarm.repeatInterval = NSCalendarUnitHour;

      NSLog(@"AlarmFireDate = %@", alarm.fireDate);
}
}

当我到达GameOverScene时,alarm.firedate在NSLog中正确显示但是当我关闭我的应用并重新启动它时,它在我的视图控制器中显示为null并且从不触发。无论用户是否使用该应用程序,如何在安排通知后让我的应用程序自动更新用户在后台的生活?它应该在我的应用代表中运行吗?

某些类型的NSDate比较如下所示吗?

if ([[NSDate date] compare:allarm.fireDate]  == NSOrderedDescending) {
    GameLives = GameLives + 1;
    NSLog(@"SUCCESS");
    NSLog(@"COUNT = %lu", (long)GameLives);
}
else if ([[NSDate date] compare:allarm.fireDate]  == NSOrderedAscending){
    GameLives = GameLives + 1;
    NSLog(@"FAILURE");
    NSLog(@"COUNT = %lu", (long)GameLives);
}
else if ([[NSDate date] compare:allarm.fireDate]  == NSOrderedSame){
    NSLog(@"SAME");
    NSLog(@"COUNT = %lu", (long)GameLives);

}

我非常感谢任何可以提供帮助的人。

编辑:对以下答案的回应

我为NSTimer编写了以下代码,当游戏到达GameOver场景时,计时器启动。

 -(void)restoreLives{

    thirtyNewMinutes = 60 * 30;
    update = [NSDate dateWithTimeIntervalSinceNow:thirtyNewMinutes];

if ([[NSDate date] compare:update]  == NSOrderedDescending) {
    NSLog(@"date1 is later than date2");
    NSLog(@"SUCCESS");
    NSLog(@"CurrentDate: %@", [NSDate date]);
  //  LifeText = @"Restored";
    GameLives = GameLives + 1;
   NSLog(@"LIVES = %ld", (long)GameLives);
//          NSLog(@"Level 2 HighScore, %d", _Level1HighScoreNumber);
} else if ([[NSDate date] compare:update]  == NSOrderedAscending) {
    NSLog(@"date1 is earlier than date2");
    NSLog(@"FAILURE");
    NSLog(@"CurrentDate: %@", [NSDate date]);
    NSLog(@"LIVES = %ld", (long)GameLives);
  //      Lives = 5;
  //      NSLog(@"dates are the same");
}

if (GameLives < 4){
    [LifeTimer invalidate];
}

然后我创建了一个NSTimer来运行该方法。

 -(void)CheckTime{
LifeTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(restoreLives) userInfo:nil repeats:YES];
}

如何保存您所说的目标时间?

并且,如果我想将当前的NSDate与[NSDate dateWithTimeIntervalSinceNow:threeNewMinutes]进行比较,我希望我不要过分思考这个问题,而是从另一个角度来看。我不需要保存[NSDate dateWithTimeIntervalSinceNow:thirtyNewMinutes]的原始日期;当它最初被调用时,如果应用程序终止并且计时器再次运行代码,则将其与调用代码的原始时间进行比较,并且不会重置NSDate并将其与用户重新启动时的30分钟进行比较应用程序和计时器再次开始。

即。 7:15

NSDate comparison to update = [NSDate dateWithTimeIntervalSinceNow:thirtyMinutes]; 

被调用。计时器设置为在7:45更新生命。

7:30用户终止他们的应用并在7:35

重新启动它

当NSTimer再次运行时,从现在起30分钟后,它将时间从7:35重置为30分钟?如果是这种情况,我将如何保存原始日期?请让我知道,请记住,我仍然是Objective C

的初学者

1 个答案:

答案 0 :(得分:1)

如果您想要通知用户某些内容,并且可以使用可用于跟踪所需信息的有效负载,则本地通知很有效,但它可能不是您进行计时工作的最佳解决方案。如果用户停用了您应用的通知,则会破坏您的功能。

相反,当谈到基于时间跟踪事件时,最好依靠日期比较和计时器。

当您的应用程序处于打开状态时,您应该使用NSTimer来触发您需要执行的操作,我认为您已经介绍过了。

当你的应用程序转到后台或终止时,你应该将目标时间保存在某种持久性存储中(例如NSUserDefaults)。重新启动应用程序或从后台返回应用程序时,您应该与该日期进行比较,然后启动计时器或触发计时器自行启动的代码。

尝试此操作以保存/恢复日期:

// Save the date with the key "NextFireDate"
[[NSUserDefaults standardUserDefaults] setObject:nextFireDate forKey:@"NextFireDate"];
// This forces the values to be saved by the system, which normally only happens periodically
[NSUserDefaults standardUserDefaults] synchronize];

...

// Retrieve the date with the key "NextFireDate"
NSDate *nextFireDate = [[NSUserDefaults standardUserDefaults] objectForKey:@"NextFireDate"];

每当你进入后台/终止(也使你的当前计时器无效)时你都会打第一个,当你完成启动或从后台返回时(第二次启动带有检索日期的新计时器),你会调用第二个。 NSUserDefaults基本上只是一个字典(可以接受标量而不必自己打包),只要您的应用程序已安装,它就会持续存在。