如果应用程序在午夜仍在运行,并且即将过渡到新的一天,我将尝试将用户返回到应用程序的第一个屏幕。
我正在使用
- (void)applicationSignificantTimeChange:(UIApplication *)application
以检测此更改,但存在一些问题。。。
首先,在9:30或10:45发生了随机触发,导致应用程序过早返回主屏幕。我知道还有其他因素可以触发这种方法,比如夏令时和运营商的消息。但这两种情况都不适用于它过早触发的那一天。
所以我在这个代码中添加了手动检查时钟小时和分钟的功能,查看设备上的时间是否在晚上11:58到凌晨12:02之间。
//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
}
通过手动调整设备时钟,这在测试中效果良好。然而,我晚上离开了这个设备,第二天早上醒来,它一直没有触发。
为什么这种方法如此挑剔?有没有更好的方法来处理我要做的事情。
你抱怨这个方法不可靠,仔细想想(注意,到10分钟前我还不知道这个方法的存在),你可以使用完全不同的方法。
从这篇文章中,我了解到你可以(通过通知)安排行动,你可以在午夜安排通知,而不是检测午夜的时间。你的弹出到root的方法会监听特定的通知,也许会检查它的有效负载以确保一些事情(这真的取决于你),如果测试通过,因为你认为它是在午夜发送的,你可以弹出。
我唯一真正不确定的是,我建议你测试一下,当应用程序处于后台/关闭状态时,是否发送了通知。
无论哪种方式,您都可以在发送通知之前轻松检查UIApplicationState,并做出相应的反应,以及当前日期和时间,因此,当用户从后台返回或重新启动应用程序或其他任何事情时,您知道要加载什么。
从头开始,没有太多的头脑风暴,以下是我对的理解
-
用户现在正在使用该应用=>通知已发送&读取,前台状态=>弹出到根
-
用户在后台有应用程序=>(不确定通知)=>无论哪种方式,都可以在NSUserDefaults中设置一些内容以加载根VC,在-
appWillEnterBackground
中 -
用户已杀死应用程序,请执行与上一步相同的操作。
这几乎用一个方法和一个通知覆盖了您的所有情况。现在你只需要测试一下,确保我没有忽视一些重要的事情。
为了弹出到根视图控制器,您可以使用:
UIApplication *application = [UIApplication sharedApplication];
[application.keyWindow.rootViewController dismissViewControllerAnimated:YES completion:nil];
大约午夜时分,我会检查一些事情,安排一个无声的本地通知。
您可以执行以下操作:
1) 当应用程序启动时,创建一个新的计时器,该计时器使用NSTimer
设置为午夜。您可以在一个地方完成步骤3)中的所有操作,以涵盖开始和恢复。用途:
- (instancetype)initWithFireDate:(NSDate *)date
interval:(NSTimeInterval)seconds
target:(id)target
selector:(SEL)aSelector
userInfo:(id)userInfo
repeats:(BOOL)repeats
使用选择器,该选择器是应用程序委派实例的一部分。
如果计时器触发,则发送本地通知并记录发送日期。
当计时器启动时,为新的一天的午夜创建一个新的计时器。
2) 使用应用程序代理调用- (void)applicationDidEnterBackground:(UIApplication *)application
来检测应用程序将进入后台。
发生这种情况时,请移除计时器并记录移除的日期。
3) 使用应用程序委派调用- (void)applicationDidBecomeActive:(UIApplication *)application
来检测应用程序是否已在前台恢复运行。
恢复午夜计时器。如前所述,1)可能可以在这个函数中完成,如果它在启动时被调用,我认为是这样
请检查上次发送通知的日期(如果有)。如果不是零,则该应用程序以前正在运行。如果现在的日期是旧日期的一天,则发送本地通知并记录日期。
摘要:
因此,如果你的应用程序正在运行,我会使用暂停/恢复通知来100%可靠地跟踪午夜滚动,并使用NSTimer可靠地告诉你现在是午夜。
使用本地通知发布可以由视图控制器拾取的事件。
为了解决这个问题,我做了以下操作。
-
当应用程序返回前台时,我会检查时间,如果新的一天过去了,我会将它们注销。
-
如果用户在交叉期间在应用程序中,我在每4分钟运行一次的后台民意调查中添加了一项检查,以检查数据,如果新的一天过去了,请将其注销。