我正在开发一个祈祷应用程序,该应用程序使用户能够为祈祷时间设置警报(本地通知),即用户将应用程序设置为每天通知他进行 Fajr 祈祷,问题是每次祈祷的时间每天都在变化,所以应用程序通知用户的时间在星期四与星期五的时间会有所不同,我需要每天重复本地通知,但根据每天的祈祷时间,请问有人能给我一个主意吗?
最佳答案
对此有几种可能的解决方案。使用一次安排有限数量通知的方法可能更安全,因为 iOS 只保留 64 个最快的通知:
An app can have only a limited number of scheduled notifications; the system keeps the soonest-firing 64 notifications (with automatically rescheduled notifications counting as a single notification) and discards the rest.
来源:UILocalNotification 类引用
依赖于使用传递给 application:didFinishLaunchingWithOptions:
的 UILocalNotification
也不是一个好主意,因为它仅在用户滑动通知时传递:
Look at the launch options dictionary to determine why your app was launched. The application:willFinishLaunchingWithOptions: and application:didFinishLaunchingWithOptions: methods provide a dictionary with keys indicating the reason that your app was launched.
启动以响应本地通知的关键值是:
UIApplicationLaunchOptionsLocalNotificationKey
来源:UIApplicationDelegate 类引用
选项 1:一次安排一天(下面提供了此代码)
处理通知安排的一种方法是向用户提供一个时间表,其中当天的通知安排在应用程序首次打开时。
使用 CustomNotificationManager
类来处理时间可变的通知(下面提供的代码)。在您的 AppDelegate 中,您可以将本地通知的处理委托(delegate)给此类,它将安排当天的通知加上第二天的固定时间通知,或者响应祈祷通知。
如果用户打开应用程序以响应祈祷通知,应用程序可以将用户引导至应用程序的适当部分。如果用户打开应用响应定时通知,应用将根据用户的日期和位置安排当天的本地通知。
选项 2(稍微精简的方法,但为用户提供的东西较少)
另一种方法是简单地使用祈祷通知的应用程序启动来安排紧随其后的应用程序启动。但是,这不太可靠,并且不提供预览通知时间表的能力。
通知管理器头文件
@interface CustomNotificationManager : NSObject
- (void) handleLocalNotification:(UILocalNotification *localNotification);
@end
通知管理器实现文件
#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, e.g. 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];
}
可能的修改建议:如果 CustomNotificationManager 需要保持状态,您可以将其转换为 Singleton。
关于ios - 如何每天不同时间重复本地通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25700890/