iphone - 在进入后台和在前台检索时将 NSTimer 的时间保存到磁盘

标签 iphone ios objective-c background nstimer

我希望我的计时器在后台工作,我认为真正做到这一点的唯一方法是在 appliationDidEnterBackground 上节省时间并使用 applicationDidLaunchWithOptions 检索它。 我的计时器使用核心数据,我的 timeInterval (testTask.timeInterval) 在每次递减后保存:

-(IBAction)startTimer:(id)sender{
    if (timer == nil) {
        [startButton setTitle:@"Pause" forState:UIControlStateNormal];
       timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
    } else {
        [startButton setTitle:@"Resume" forState:UIControlStateNormal];
        [timer invalidate];
        timer = nil;
    }

}
-(void)timerAction:(NSTimer *)t
{
    if(testTask.timeInterval == 0)
    {
        if (self.timer)
        {
            [self timerExpired];
            [self.timer invalidate];
            self.timer = nil;
        }
    }
    else
    {
        testTask.timeInterval--;
        NSError *error;
        if (![self.context save:&error]) {
            NSLog(@"couldn't save: %@", [error localizedDescription]);
        }
    }
    NSUInteger seconds = (NSUInteger)round(testTask.timeInterval);
    NSString *string = [NSString stringWithFormat:@"%02u:%02u:%02u",
                        seconds / 3600, (seconds / 60) % 60, seconds % 60];
    timerLabel.text = string;
    NSLog(@"%f", testTask.timeInterval);
}
-(void)timerExpired{
    UILocalNotification* localNotification = [[UILocalNotification alloc] init];
    localNotification.alertBody = @"Time is up";
    localNotification.alertAction = @"Ok";
    localNotification.timeZone = [NSTimeZone defaultTimeZone];
    [[UIApplication sharedApplication]presentLocalNotificationNow:localNotification];
}

这些方法在一个细节 View Controller 中,它是这样初始化的:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    DetailViewController *detailVC;
    if (![self.detailViewsDictionary.allKeys containsObject:indexPath]){
        detailVC = [[DetailViewController alloc]initWithNibName:@"DetailViewController" bundle:nil];
        [self.detailViewsDictionary setObject:detailVC forKey:indexPath];
        detailVC.context = self.managedObjectContext;
    }else{
        detailVC = self.detailViewsDictionary[indexPath];
    }
        Tasks *task = [[self fetchedResultsController] objectAtIndexPath:indexPath];
        detailVC.testTask = task;
        [[self navigationController] pushViewController:detailVC animated:YES];
    NSLog(@"%@", self.detailViewsDictionary);
}

我不明白的是......我如何访问 timeInterval(每个 detailviewcontroller 都有不同的时间间隔......)以便我可以将它放在 appliationDidEnterBackground 中?另外,我猜我应该把应用程序进入后台的时间保存下来,然后再保存进入前台的时间,然后减去?然后我将从时间间隔中减去该值,对吗?

最佳答案

首先,如果您非常在意准确性,就不应该使用这样的直接倒计时。 NSTimer 不会以精确的一秒间隔触发,延迟会累积。更好的方法是在计时器启动时创建一个 NSDate,并在每次滴答时获取 NSTimeInterval,然后计算分钟和秒。

为每个 View Controller 存储自己的开始时间,您可以注册任何对象来接收 UIApplicationDidEnterBackgroundNotification .这是在应用程序委托(delegate)获取 applicationDidEnterBackground: 的同时发布的。

Also, I am guessing I should save the time that the application enters the background and then save the time when it enters the foreground, and subtract? and then I would subtract that value from the timeinterval, correct?

是的:

NSTimeInterval idleTime = [dateReturnedToForeground timeIntervalSinceDate:dateEnteredBackground];
NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSinceDate:startDate];
elapsedTime -= idleTime;

将为您提供计时器已用完的事件时间。

关于iphone - 在进入后台和在前台检索时将 NSTimer 的时间保存到磁盘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18175512/

相关文章:

ios - 如何使用 UIView 创建自定义翻转动画

ios - 从 Swift 中的回调返回对象

ios - UIAlertController 位置错误

ios - 您将如何追溯导入框架的来源?

iphone - 如何在iPhone的NSdata中放入音频歌曲

IPhone 应用程序和 iPad 视网膜图标

iPhone 应用程序设计 Storyboard与 nib

iphone - 将本地 SQLite 数据库复制到 iPhone?

iphone - 当我在 iOS 中返回查看时,导航栏被隐藏

iphone - 使用 NSMutableArray 与 NSArray 的缺点?