有一个NSTimer运行背景

我已经看到了数百个如何让NSTimer在后台运行的解决scheme。

我知道这是可能的,只要看看像Strava和Runkepper这样的应用程序,可以跟踪你锻炼的时间。

但是,这样做的最佳实践解决scheme是什么? 我无法find一个解决scheme。

另外,我希望NSTimer可以在不同的UIViewControllers中使用。 这是怎么做的最佳做法?

谢谢你的问候! 🙂

NSTimers不会在后台运行。 当您获得背景时,存储当前时间和计时器的运行时间。 当您回到前台时,您将设置一个新的计时器,使用这两个信息设置需要反映总时间的任何状态或数据。 为了在viewCOntroller之间共享,只需要一个对象实现这个定时器,并且暴露一个属性(例如elapsedTime),并且每隔一段时间更新一次。 然后你可以让viewCOntrollers(有一个对该对象的引用)观察该属性的变化。

您可以在您的应用程序中尝试此代码NSTimers不会在后台运行。 join苹果,但我们强制尝试只有3薄荷
AppDelegate.h

 @property (nonatomic, unsafe_unretained) UIBackgroundTaskIdentifier backgroundTaskIdentifier; @property (nonatomic, strong) NSTimer *myTimer; - (BOOL) isMultitaskingSupported; - (void) timerMethod:(NSTimer *)paramSender; 

AppDelegate.m

  - (void)applicationDidEnterBackground:(UIApplication *)application { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. if ([self isMultitaskingSupported] == NO) { return; } self.myTimer =[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(timerMethod:) userInfo:nil repeats:YES]; self.backgroundTaskIdentifier =[application beginBackgroundTaskWithExpirationHandler:^(void) { [self endBackgroundTask]; }]; } 

编译标记 – NSTimer过程

 - (BOOL) isMultitaskingSupported { BOOL result = NO; if ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)]){ result = [[UIDevice currentDevice] isMultitaskingSupported]; } return result; } - (void) timerMethod:(NSTimer *)paramSender{ NSTimeInterval backgroundTimeRemaining = [[UIApplication sharedApplication] backgroundTimeRemaining]; if (backgroundTimeRemaining == DBL_MAX) { NSLog(@"Background Time Remaining = Undetermined"); } else { NSLog(@"Background Time Remaining = %.02f Seconds",backgroundTimeRemaining); } } - (void) endBackgroundTask { dispatch_queue_t mainQueue = dispatch_get_main_queue(); __weak AppDelegate *weakSelf = self; dispatch_async(mainQueue, ^(void) { AppDelegate *strongSelf = weakSelf; if (strongSelf != nil){ [strongSelf.myTimer invalidate]; [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskIdentifier]; strongSelf.backgroundTaskIdentifier = UIBackgroundTaskInvalid; } }); } 

在这里输入图像说明

正如评论中指出的那样, NSTimer不会在后台工作,iOS上的后台执行相当棘手,只有在某些情况下才起作用,请检查Apple Docs的主题, 这也是获得更多背景知识的绝佳读物 。

至于你的情况,听起来像你想使用UILocalNotification 。 正如我从你的评论中所理解的: I want to have a timer running while the app is not in the foreground. Just like Apples own timer app. I want to have a timer running while the app is not in the foreground. Just like Apples own timer app.

苹果的计时器应用程序使用UILocalNotification 。 它给你一个方法来安排一个通知,这个通知会在某个时间点出现给用户,不pipe这个app是在前台还是在后台! 所有你需要做的是在你的应用程序安排一个通知,例如像这样:

 UILocalNotification *localNotification = [[UILocalNotification alloc] init]; localNotification.fireDate = dateTime; localNotification.alertBody = [NSString stringWithFormat:@"Alert Fired at %@", dateTime]; localNotification.soundName = UILocalNotificationDefaultSoundName; [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; 

然后iOS会为你处理其余的问题:)