最近项目中要用到类似天猫日历提醒功能,网上找了很多资料跟实际需求有出入,换是决定自己写一下,语言描述能力有限直接上代码,项目中有比较详尽的注释,附Demo地址:
https://github.com/876450979/ZJWEvent.git
友情提示
在plist文件中加入权限描述,防止审核不通过和崩溃哦
<key>NSCalendarsUsageDescription</key>
<string>App需要您的同意,才能访问日历</string>
<key>NSRemindersUsageDescription</key>
<string>App需要您的同意,才能访问提醒事项</string>
1,添加日历提醒
/**
* 将App事件添加到系统日历提醒事项,实现闹铃提醒的功能
*
* @param title 事件标题
* @param location 事件位置
* @param startDate 开始时间
* @param endDate 结束时间
* @param allDay 是否全天
* @param alarmArray 闹钟集合
*/
func createEventCalendarTitle(title: String, location: String, startDate: Date, endDate: Date, allDay: Bool, alarmArray: Array<String>) {
EventCalendar.eventStore.requestAccess(to: EKEntityType.event) { [unowned self] (granted, error) in
DispatchQueue.main.async {
//用户没授权
if !granted {
let alertViewController = UIAlertController(title: "提示", message: "请在iPhone的\"设置->隐私->日历\"选项中,允许***访问你的日历。", preferredStyle: .alert)
let actionCancel = UIAlertAction(title: "取消", style: .cancel, handler: { (action) in
})
let actinSure = UIAlertAction(title: "设置", style: .default, handler: { (action) in
//跳转到系统设置主页
if let url = URL(string: UIApplicationOpenSettingsURLString) {
//根据iOS系统版本,分别处理
if #available(iOS 10, *) {
UIApplication.shared.open(url)
} else {
UIApplication.shared.openURL(url)
}
}
})
alertViewController.addAction(actionCancel)
alertViewController.addAction(actinSure)
self.present(alertViewController, animated: true, completion: nil)
return
}
//允许
if granted {
//过滤重复事件
let predicate = EventCalendar.eventStore.predicateForEvents(withStart: startDate, end: endDate, calendars: nil) //根据时间段来筛选
let eventsArray = EventCalendar.eventStore.events(matching: predicate)
if eventsArray.count > 0 {
for item in eventsArray {
//根据事件唯一性,如果已经插入的就不再插入了
if let start = item.startDate, let end = item.endDate {
if start == startDate && end == endDate {
return
}
}
}
}
let event = EKEvent(eventStore: EventCalendar.eventStore)
event.title = title
event.location = location
event.startDate = startDate
event.endDate = endDate
event.isAllDay = allDay
//添加提醒时间(提前)
if alarmArray.count > 0 {
for timeString in alarmArray {
if let time = TimeInterval(timeString) {
event.addAlarm(EKAlarm(relativeOffset: TimeInterval(time)))
}
}
}
event.calendar = EventCalendar.eventStore.defaultCalendarForNewEvents //必须设置系统的日历
do {
try EventCalendar.eventStore.save(event, span: EKSpan.thisEvent)
}catch{}
print("事件ID--\(event.eventIdentifier)") //系统随机生成的,需要保存下来,下次删除使用
self.eventId = event.eventIdentifier //保存本次事件id 可以通过后台返回的id做这次保存的key值,偏好设置保存
print("成功添加到系统日历中")
}
}
}
}
2,删除日历中指定事件
///删除指定事件 根据事件id来删除
func removeEventCalendar(idfer: String) {
guard let event = EventCalendar.eventStore.event(withIdentifier: idfer) else {
return
}
do {
try EventCalendar.eventStore.remove(event, span: EKSpan.thisEvent)
} catch {}
print("删除成功")
}
3,删除某一时间段事件
ps:(删除会把这一时间段所有的事件都删除,包括用户自己设置的事件,慎用慎用慎用 重要的事说三遍)
///删除某个时间段所有的事件(会删除这个时间段所有时间,包括用户自己添加的)
func removeAllEventCalendar(startDate: Date, endDate: Date) {
let predicate = EventCalendar.eventStore.predicateForEvents(withStart: startDate, end: endDate, calendars: nil) //根据时间段来筛选
let eventsArray = EventCalendar.eventStore.events(matching: predicate)
if eventsArray.count > 0 {
for item in eventsArray {
//删除老版本插入的提醒
do {
try EventCalendar.eventStore.remove(item, span: EKSpan.thisEvent, commit: true)
}catch{}
print("删除过期时间成功")
}
}
}