目标C语言 使用UILocalNotification恢复游戏生活



我正在Spritekit中创造一款游戏,我尝试着让玩家在失去所有命值后需要等待30分钟才能恢复其中一条命值,以便他们能够再次体验游戏。我尝试使用NSTimer来做到这一点,但我认为uninotification会更有效,因为我想要这个计时器运行,无论应用程序是否被终止,在后台,被使用或不被使用。我在设置这个时遇到了问题。

到目前为止,当用户到达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时,firedate在NSLog中正确显示但当我关闭我的应用程序并重启它时,它在我的视图控制器中显示为空并且从不触发。我如何让我的应用程序在后台自动更新用户的生活,一旦通知被安排,无论用户是否在使用应用程序?它应该在我的app委托中运行吗?

应该像下面这样的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);
}

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

编辑:对下面的答案的回应

我为ntimer编写了以下代码,计时器在游戏到达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:thirtyNewMinutes];我不需要保存原始日期[NSDate dateWithTimeIntervalSinceNow:thirtyNewMinutes];当它最初被调用时,如果应用程序终止并且计时器再次运行代码,它将其与代码被调用的原始时间进行比较,并且不重置NSDate并将其与用户重启应用程序和计时器再次开始的时间30分钟进行比较。

。7:15

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

。计时器设定在7:45更新生命

7:30用户终止他们的应用程序并在7:35重新启动

当NSTimer再次运行时,它不会将时间从7:35重置为30分钟,因为它是从现在开始30分钟?如果是这样,我该如何保存原始日期呢?请让我知道,记住我仍然是Objective C的初学者

如果你想要通知用户一些事情,那么本地通知就很有效,并且可以使用有效负载来跟踪你需要的信息,但这可能不是你做计时工作的最佳解决方案。如果用户禁用应用程序的通知,它会破坏你的功能。

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

当你的应用程序打开时,你应该使用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基本上只是一个字典(可以接受标量,而不必自己装箱),只要你的应用程序安装持续

最新更新