如果应用仍在运行,则在午夜时播放到根视图

时间:2015-04-29 13:17:47

标签: ios objective-c

我试图将用户返回到应用程序的第一个屏幕,如果应用程序仍然在午夜运行并且即将过渡到新的一天。

我正在使用

- (void)applicationSignificantTimeChange:(UIApplication *)application

检测到这种变化,但存在一些问题......

首先,在9:30或10:45发生了随机触发,导致应用程序过早地回到主屏幕。我知道有其他因素可以触发这种方法,例如夏令时和来自运营商的消息。但这些都不适用于它过早触发的那一天。

所以我在这段代码中添加了手动检查时钟小时和分钟检查以查看设备上的时间是否在11:58 PM到12:02 AM之间。

      //Get current time
NSDate* now = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dateComponents = [gregorian components:(NSHourCalendarUnit  | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:now];
NSInteger hour = [dateComponents hour];
NSInteger minute = [dateComponents minute];

if ((hour>=23 && minute > 58) || (hour == 0 && minute < 2))
{
   //return to main screen
}

通过手动调整设备时钟,这在测试中运行良好。然而,我离开了设备过夜,第二天早上醒来,它从未触发过。

为什么这种方法如此挑剔?是否有更好的方法来处理我正在尝试做的事情。

4 个答案:

答案 0 :(得分:0)

你抱怨这种方法不可靠,并且想到它(注意我从10分钟前就不知道这种方法的存在),你可以使用一种完全不同的方式。

来自this post我知道您可以安排行动(通过通知),而不是在午夜时间检测,而是在午夜安排通知。 弹出到root的方法会听取特定的通知,也可以检查它的有效负载,以确定一些事情(这真的取决于你),如果测试通过,因为你认为它和&#39。 #39;已经在午夜发送,你可以弹出。

我唯一不确定但我建议您测试的是当应用程序处于后台/被杀时是否发送通知。

无论哪种方式,您都可以在发送通知之前轻松检查UIApplicationState并做出相应的反应,以及当前的日期和时间,因此,当用户从后台返回或重新启动应用程序或其他任何内容时,您知道什么加载。

从零开始,没有太多的头脑风暴,这就是我理解的方式

  • 用户现在正在使用该应用=&gt;通知已发送&amp;读取,前景状态=&gt; pop to root

  • 用户在背景中有app =&gt; (对通知不确定)=&gt;无论哪种方式,在NSUserDefaults中设置一些东西来加载根VC,在 - appWillEnterBackground

  • 用户已杀死app,请执行上一步操作。

通过一种方法和一种通知,这几乎涵盖了所有情况。现在你只需要测试它,以确保我没有忽略重要的事情。

答案 1 :(得分:0)

要弹出到根视图控制器,您可以使用:

UIApplication *application = [UIApplication sharedApplication];
[application.keyWindow.rootViewController dismissViewControllerAnimated:YES completion:nil];

关于午夜解雇,我会检查安排silent local notification的方式。

答案 2 :(得分:0)

您可以执行以下操作:

1)当应用程序启动时,使用NSTimer创建一个设置为午夜的新计时器。您可以在一个地方完成步骤3)中的所有操作,以涵盖开始和恢复。使用:

- (instancetype)initWithFireDate:(NSDate *)date
                        interval:(NSTimeInterval)seconds
                          target:(id)target
                        selector:(SEL)aSelector
                        userInfo:(id)userInfo
                         repeats:(BOOL)repeats

使用属于您的app代理实例的选择器。

如果计时器触发,则发送本地通知并记录发送日期。

当计时器触发时,在新的一天为午夜创建一个新的计时器。

2)使用app delegate call - (void)applicationDidEnterBackground:(UIApplication *)application检测应用程序转到后台。

发生这种情况时,请删除计时器并记录删除的日期。

3)使用app delegate call - (void)applicationDidBecomeActive:(UIApplication *)application检测应用程序已在前台恢复运行。

为午夜恢复计时器。如上所述1)如果在启动时调用它,也许可以在这个函数中完成,我认为它是。

检查上次发送通知的日期(如果有)。如果它不是零,应用程序之前运行。如果现在的日期是从旧日期开始的一天,则发送本地通知并记录日期。

要点:

因此,我会使用暂停/恢复通知100%可靠地跟踪午夜翻转,并使用NSTimer可靠地告诉您,如果您的应用正在运行,它是午夜。

使用本地通知发布可由视图控制器拾取的事件。

答案 3 :(得分:0)

为了解决这个问题,我做了以下几点。

  1. 当应用程序返回到前台时,我会检查时间,如果新的一天过去了,我会将它们注销。

  2. 如果用户在交叉期间处于应用内,我在每4分钟运行一次的后台轮询期间添加了一项检查以检查数据,如果新的一天过去了,请将其注销