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

问题描述:

我正在开发一个祈祷应用程序,使用户能够为祷告时间设置闹钟(本地通知),即用户设置应用程序以便每天通知Fajr祷告,问题在于每个祷告的时间每天都在变化,所以在星期四应用程序将通知用户公平的时间将与星期五的时间不同,我需要每天重复本地通知,但根据每日祷告时间,请,谁能给我一个想法?如何在不同的时间每天重复本地通知

+0

你有没有想出解决办法?我最终计算了未来10天的祈祷,并以这种方式安排通知。唯一的情况是有大约50个通知限制,所以我必须为用户设置另一个通知来打开我的应用程序,以便从那里开始下一个10天。不喜欢它,但只有我能想到的方式。 – TruMan1 2016-03-06 17:17:55

+0

http://*.com/questions/9862261/local-notification-repetation-at-different-times – TruMan1 2016-03-06 17:24:23

+0

@ TruMan1:你想让用户设置时间,还是你想让应用程序设置时间用户?而且,这个时间应该增加多少时间?我很想提供一些实现,但我需要更多信息。 :) – Sheamus 2016-03-07 07:33:46

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

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

欲了解更多信息,指的是苹果公司在后台执行文件:

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

+0

有趣的,关于注册后台获取的好主意只是为了计算和安排将来的通知。 – TruMan1 2016-03-06 17:42:25

这有几个可能的解决方案。因为iOS只保留64条最快的通知,所以使用一种方法可能会更安全一些,因为iOS只保留64条最快的通知:

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

来源:UILocalNotification类参考

它也不是靠使用传入application:didFinishLaunchingWithOptions:UILocalNotification一个好主意,因为它是当用户刷卡的通知只有通过:

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

,用于响应发射到本地通知的密钥值是: UIApplicationLaunchOptionsLocalNotificationKey

来源:UIApplicationDelegate类参考

选项1:日程一天一时间(码本在下面提供)

处理通知调度的一种方式是向用户呈现时间表,whe当天的通知安排在应用程序初次启用时。

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

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

选项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。

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

  1. 使用推送通知,而不是本地通知和移动逻辑服务器。问题 - 用户在脱机时不会收到通知。

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

  3. 而是创建本地通知,创建设备日历闹钟/提醒(Event Kit