关于日历中重复事件的需求

发布
更新
字数 494
阅读 3 分钟
阅读量 993

重复事件的规则实现,可以参考 EKRecurrenceRule,但通常还有额外的需求,例如在日历中标记或者设置提醒。日历标记,如果是使用 EventKit ,可以指定范围进行搜索获得,参考 https://developer.apple.com/documentation/eventkit/retrieving_events_and_reminders。提醒也是可以通过系统 API 进行设置的。这里仅讨论自己实现相应逻辑时一些额外的需求。

需求1:日历标记

在日历视图中要把事件重复日期全部标出来,需要一个方法,可以在指定日期范围内根据重复规则生成对应的日期

protocol DatesMatchingRecurrenceRule{
    static func dates(matching recurrenceRule:RecurrenceRule, withStart start: Date, end: Date) -> [Date]
}

需求2:设置提醒

应用内的提醒都是通过 UNNotification 实现,目前可用的 trigger 有两种,UNTimeIntervalNotificationTriggerUNCalendarNotificationTrigger

Time interval 通知类似于计时器,即从现在开始出发,直到指定时间就会发送通知,如果设置了 repeat 则在触发时重新计时再次等待到时提醒。

Calendar 通知基于 DateComponents 设置触发时间,如果重复,会根据 components 的范围选取重复规则,例如以下代码会在每天早上八点半触发通知

var date = DateComponents()
date.hour = 8
date.minute = 30 
let trigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)

Calendar 通知比较适合为重复事件设置通知,例如 每月第一个周三,可以设置 components 为

var date = DateComponents()
date.weekOfMonth = 1
date.weekday = 3

如果规则比较复杂,就需要设置多个通知,设置通知时,最好设置一个标识符前缀,这样当取消通知时,可以通过 func getPendingNotificationRequests(completionHandler: @escaping ([UNNotificationRequest]) -> Void) 方法获取并过滤取的对应的 identifiers,也可以把 identifiers 保存在本地(不需要同步),然后通过 funcremovePendingNotificationRequests(withIdentifiersidentifiers: [String]) 方法取消通知。