2015-05-27 4 views
0

Я создаю игру в Spritekit, и я пытаюсь настроить свою игру таким образом, что, когда игрок теряет всю свою жизнь, им приходится ждать 30 минут, чтобы одна из их жизней была чтобы они снова могли играть. Я попытался использовать NSTimer для этого, но я решил, что UINotification будет более эффективным, так как я хочу, чтобы этот таймер запускался независимо от того, прекращено ли приложение в фоновом режиме, используется или не используется. Однако у меня проблемы с настройкой.Восстановление игровой жизни с использованием UILocalNotification

Я следующий код, написанный до сих пор, когда пользователь достигает 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); 
} 
} 

alarm.firedate отображается корректно в NSLog, когда я достичь GameOverScene, но когда я закрыть мое приложение и перезапустить он отображается как 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); 

} 

Я был бы очень признателен всем, кто может оказать помощь.

EDIT: ОТВЕТ НА ОТВЕТЫ НИЖЕ

Я написал следующий код для 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: тридцать новых пользователей]; мне не нужно сохранять исходную дату [NSDate dateWithTimeIntervalSinceNow: тридцать новых пользователей]; когда это изначально было вызвано так, что если приложение завершается, и таймер запускает код снова, он сравнивает его с исходным временем, когда код вызывался, и не сбрасывает NSDate и сравнивает его с 30 минутами с момента перезапуска приложения и таймер начнется снова.

т.е. 7:15

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

называется. И таймер установлен для обновления жизни в 7:45.

7:30 Пользователь завершает свое приложение и перезапускает его в 7:35

Когда NSTimer запускается снова не будет его сбросить время, чтобы быть в 30 минутах от 7:35, так как это 30 минут с этого момента? Если это так, как я могу сохранить первоначальную дату? Пожалуйста, дайте мне знать, имейте в виду, что я все еще новичок в Objective C

+0

Зачем использовать уведомление? Просто отслеживайте, когда нужно добавить жизнь. Используйте NSTimer, чтобы уйти в это время. Если пользователь закрывает приложение и позже перезагружается, вы смотрите на то, что сэкономленное время выключения, и снова настройте таймер, если осталось время, иначе вы даете новую жизнь. – rmaddy

+0

Спасибо за ваш ответ, но как вы собираетесь сохранить исходное NSDate или целевое время, когда приложение будет прекращено? Не могли бы вы предложить примерный код? – John

+0

Сохраните его в 'NSUserDefaults'. – rmaddy

ответ

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 - это в основном просто словарь (который может принимать скаляры, не загружая их самостоятельно), который сохраняется до тех пор, пока ваше приложение установлено.

+0

Спасибо за ваш ответ, но как бы вы решили сохранить целевое время? Не могли бы вы предложить примерный код? – John

+0

Пожалуйста, посмотрите на ответ, который я написал ниже, поскольку раздел комментариев не позволит мне писать все символы, которые я хотел написать – John

+0

. Итак, вы бы поместили этот код в делегат приложения? Всякий раз, когда этот метод называется? Или оба?? – John

Смежные вопросы