如何在不同的时间每天重复本地通知

我正在做一个祈祷应用程序,使用户能够为祈祷时间设置警报(本地通知),即用户设置应用程序通知他每天的祈祷祷告,问题是每个祷告的时间每天都在变化应用程序在星期四通知用户公平的时间将与星期五的时间有所不同,我需要每天重复本地通知,但是根据每天的祷告时间,请有谁能给我一个想法?

有几个可能的解决scheme。 使用一次安排数量有限的通知的方法可能更安全,因为iOS只保留64个最快的通知:

一个应用程序只能有有限数量的预定通知; 系统保持最快的64个通知(自动重新安排的通知作为单个通知计数),并丢弃剩下的通知。

来源:UILocalNotification类参考

依靠使用传递给application:didFinishLaunchingWithOptions:UILocalNotification application:didFinishLaunchingWithOptions:也不是一个好主意,因为只有在用户滑动通知时才传递:

查看启动选项字典以确定您的应用程序启动的原因。 应用程序:willFinishLaunchingWithOptions:和application:didFinishLaunchingWithOptions:方法提供一个字典,其中包含指示您的应用程序启动的原因的键。

启动响应本地通知的键值为: UIApplicationLaunchOptionsLocalNotificationKey

来源:UIApplicationDelegate类的参考

选项1:每天计划一天(以下提供代码)

处理通知日程安排的一种方法是向用户提供日程安排,其中在应用程序初始打开时计划当天的通知。

使用CustomNotificationManager类来处理时间可变的通知(下面提供的代码)。 在你的AppDelegate中,你可以委托这个类处理本地通知,它将会安排当天的通知加上第二天的固定时间通知,或者响应祈祷通知。

如果用户打开应用程序以响应祷告通知,则应用程序可以将用户引导至应用程序的适当部分。 如果用户打开应用程序以响应固定时间的通知,则应用程序将根据用户的date和地点安排当天的本地通知。

选项2(略微更薄的方法,但提供较less的用户)

另一种方法是简单地使用祈祷通知的应用程序启动来安排紧随其后的一个。 但是,这不太可靠,并且不能提供预览通知时间表的function。

通知pipe理器头文件

 @interface CustomNotificationManager : NSObject - (void) handleLocalNotification:(UILocalNotification *localNotification); @end 

通知pipe理器实施文件

 #import "CustomNotificationManager.h" #define CustomNotificationManager_FirstNotification @"firstNotification" @implementation CustomNotificationManager - (instancetype) init { self = [super init]; if (self) { } return self; } - (void) handleLocalNotification:(UILocalNotification *)localNotification { //Determine if this is the notification received at a fixed time, // used to trigger the scheculing of today's notifications NSDictionary *notificationDict = [localNotification userInfo]; if (notificationDict[CustomNotificationManager_FirstNotification]) { //TODO: use custom algorithm to create notification times, using today's date and location //Replace this line with use of algorithm NSArray *notificationTimes = [NSArray new]; [self scheduleLocalNotifications:notificationTimes]; } else { //Handle a prayer notification } } /** * Schedule local notifications for each time in the notificationTimes array. * * notificationTimes must be an array of NSTimeInterval values, set as intervalas * since 1970. */ - (void) scheduleLocalNotifications:(NSArray *)notificationTimes { for (NSNumber *notificationTime in notificationTimes) { //Optional: create the user info for this notification NSDictionary *userInfo = @{}; //Create the local notification UILocalNotification *localNotification = [self createLocalNotificationWithFireTimeInterval:notificationTime alertAction:@"View" alertBody:@"It is time for your next prayer." userInfo:userInfo]; //Schedule the notification on the device [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; } /* Schedule a notification for the following day, to come before all other notifications. * * This notification will trigger the app to schedule notifications, when * the app is opened. */ //Set a flag in the user info, to set a flag to let the app know that it needs to schedule notifications NSDictionary *userInfo = @{ CustomNotificationManager_FirstNotification : @1 }; NSNumber *firstNotificationTimeInterval = [self firstNotificationTimeInterval]; UILocalNotification *firstNotification = [self createLocalNotificationWithFireTimeInterval:firstNotificationTimeInterval alertAction:@"View" alertBody:@"View your prayer times for today." userInfo:userInfo]; //Schedule the notification on the device [[UIApplication sharedApplication] scheduleLocalNotification:firstNotification]; } - (UILocalNotification *) createLocalNotificationWithFireTimeInterval:(NSNumber *)fireTimeInterval alertAction:(NSString *)alertAction alertBody:(NSString *)alertBody userInfo:(NSDictionary *)userInfo { UILocalNotification *localNotification = [[UILocalNotification alloc] init]; if (!localNotification) { NSLog(@"Could not create a local notification."); return nil; } //Set the delivery date and time of the notification long long notificationTime = [fireTimeInterval longLongValue]; NSDate *notificationDate = [NSDate dateWithTimeIntervalSince1970:notificationTime]; localNotification.fireDate = notificationDate; //Set the slider button text localNotification.alertAction = alertAction; //Set the alert body of the notification localNotification.alertBody = alertBody; //Set any userInfo, eg userID etc. (Useful for app with multi-user signin) //The userInfo is read in the AppDelegate, via application:didReceiveLocalNotification: localNotification.userInfo = userInfo; //Set the timezone, to allow for adjustment for when the user is traveling localNotification.timeZone = [NSTimeZone localTimeZone]; return localNotification; } /** * Calculate and return a number with an NSTimeInterval for the fixed daily * notification time. */ - (NSNumber *) firstNotificationTimeInterval { //Create a Gregorian calendar NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; //Date components for next day NSDateComponents *dateComps = [[NSDateComponents alloc] init]; dateComps.day = 1; //Get a date for tomorrow, same time NSDate *today = [NSDate date]; NSDate *tomorrow = [cal dateByAddingComponents:dateComps toDate:today options:0]; //Date components for the date elements to be preserved, when we change the hour NSDateComponents *preservedComps = [cal components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:tomorrow]; preservedComps.hour = 5; tomorrow = [cal dateFromComponents:preservedComps]; NSTimeInterval notificationTimeInterval = [tomorrow timeIntervalSince1970]; NSNumber *notificationTimeIntervalNum = [NSNumber numberWithLongLong:notificationTimeInterval]; return notificationTimeIntervalNum; } @end 

AppDelegate didReceiveLocalNotification实现

 - (void) application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { CustomNotificationManager *notificationManager = [[CustomNotificationManager alloc] init]; [notificationManager handleLocalNotification:notification]; } 

对可能的修改build议:如果CustomNotificationManager需要维护状态,可以将其转换为单例。

所以问题出现,你需要设置这个本地通知时不时,但不能是一个可重复的通知。 我假设用户设置祈祷时间,并希望得到通知。 我build议你设置一些,因为你从列表中知道。 然后设置每5个小时的背景获取,并在应用程序后台启动时,只需检查本地通知是否仍然设置,并根据当前date相应地更新列表。 在这种情况下,后台抓取并不会精确地每5个小时唤醒一次您的应用程序,但会尽其所能。 我相信你的应用一天至less会醒来两次。 你可以根据你的需要调整时间。

获取less量内容机会性需要定期检查新内容的应用程序可以要求系统将其唤醒,以便他们可以启动对该内容的提取操作。 要支持这种模式,请在Xcode项目的Capabilities选项卡的Background modes部分启用Background fetch选项。 (您也可以通过在应用程序的Info.plist文件中包含具有获取值的UIBackgroundModes键来启用此支持。)启用此模式并不能保证系统将随时为您的应用程序提供后台提取。 系统必须平衡您的应用程序的需求,以获取其他应用程序和系统本身的需求。 在评估这些信息之后,如果有这样的机会,系统会给应用程序一些时间。 当出现好机会时,系统会唤醒或启动您的应用程序,并调用应用程序委托的应用程序:performFetchWithCompletionHandler:方法。 如果内容可用,请使用该方法检查新内容并启动下载操作。 一旦完成下载新内容,您必须执行提供的完成处理程序块,并传递一个结果,指示内容是否可用。 执行此块会告诉系统它可以将您的应用程序移回暂停状态并评估其用电量。 快速下载less量内容的应用程序,准确地反映何时可以下载的内容,与将需要很长时间下载内容的应用程序相比,未来可能会收到执行时间,或者声明内容可用,但不下载任何东西。

有关更多信息,请参阅Apple的后台执行文档:

https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

有三种方法可以做到这一点:

  1. 使用推送通知而不是本地通知,并将逻辑移动到服务器。 问题 – 用户离线时不会收到通知。

  2. 继续使用本地通知。 你将不得不为每个祈祷时间计划一个新的通知。 当然,本地通知的数量是有限的(最多64预定通知),但是一周通知就足够了。 通知不是警报,用户应该接收到通知后才能打开应用程序。 这样,当应用程序重新打开时,您可以随时重新安排所有通知。 此外,最后的通知可能类似于“您暂时未打开应用程序,您将不会收到更多通知”。

  3. 在您的设备日历( Event Kit )中创build闹钟/提醒,而不是创build本地通知。