Swift - 使用EventKit获取系统日历事件,添加事件
通过 EventKit 可以对 iOS 日历事件进行读取,添加等操作。但网上找到的都是使用 Objective-C 来编写的。
![](/blog_uploads/201610/2016100610191478510.png)
3,功能改进:只查询本地日历中的事件
从上面的运行结果可以看出,我们把系统中所有的日历事件都查询出来了,不管是本地日历事件(如果有iCloud同步则是iCloud日历),还是系统自带的节假日、生日日历事件。如果我们只关注本地日历事件,可以在查询的时候添加个日历参数即可。代码如下。![](/blog_uploads/201610/2016100610451552273.png)
下面提供一个 Swift 版的样例,演示如何添加一个事件以及获取所有的事件列表。
1,首先配置info.plist
从 iOS10 起,苹果增强对用户的安全和隐私的保护。在申请很多私有权限的时候都需要添加描述。我们这里需要访问日历,那就需要在 info.plist 添加日历相关的描述字段。
字段名:NSCalendarsUsageDescription 。描述随便,我这里就写“App需要您的同意,才能访问日历”。
字段名:NSCalendarsUsageDescription 。描述随便,我这里就写“App需要您的同意,才能访问日历”。
![](/blog_uploads/201610/2016100610172996759.png)
2,代码如下(已升级至Swift3)
import UIKit import EventKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let eventStore = EKEventStore() // 'EKEntityType.reminder' or 'EKEntityType.event' eventStore.requestAccess(to: .event, completion: { granted, error in if (granted) && (error == nil) { print("granted \(granted)") print("error \(error)") // 新建一个事件 let event:EKEvent = EKEvent(eventStore: eventStore) event.title = "新增一个测试事件" event.startDate = Date() event.endDate = Date() event.notes = "这个是备注" event.calendar = eventStore.defaultCalendarForNewEvents do{ try eventStore.save(event, span: .thisEvent) print("Saved Event") }catch{} // 获取所有的事件(前后90天) let startDate = Date().addingTimeInterval(-3600*24*90) let endDate = Date().addingTimeInterval(3600*24*90) let predicate2 = eventStore.predicateForEvents(withStart: startDate, end: endDate, calendars: nil) print("查询范围 开始:\(startDate) 结束:\(endDate)") if let eV = eventStore.events(matching: predicate2) as [EKEvent]! { for i in eV { print("标题 \(i.title)" ) print("开始时间: \(i.startDate)" ) print("结束时间: \(i.endDate)" ) } } } }) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } }运行结果:
![](/blog_uploads/201610/2016100610190523901.png)
![](/blog_uploads/201610/2016100610191478510.png)
3,功能改进:只查询本地日历中的事件
从上面的运行结果可以看出,我们把系统中所有的日历事件都查询出来了,不管是本地日历事件(如果有iCloud同步则是iCloud日历),还是系统自带的节假日、生日日历事件。如果我们只关注本地日历事件,可以在查询的时候添加个日历参数即可。代码如下。
import UIKit import EventKit class ViewController: UIViewController { let eventStore = EKEventStore() override func viewDidLoad() { super.viewDidLoad() // 请求日历事件 eventStore.requestAccess(to: .event, completion: { granted, error in if (granted) && (error == nil) { print("granted \(granted)") print("error \(error)") //获取本地日历(剔除节假日,生日等其他系统日历) let calendars = self.eventStore.calendars(for: .event).filter({ (calender) -> Bool in return calender.type == .local || calender.type == .calDAV }) // 获取所有的事件(前后90天) let startDate = Date().addingTimeInterval(-3600*24*90) let endDate = Date().addingTimeInterval(3600*24*90) let predicate2 = self.eventStore.predicateForEvents(withStart: startDate, end: endDate, calendars: calendars) print("查询范围 开始:\(startDate) 结束:\(endDate)") if let eV = self.eventStore.events(matching: predicate2) as [EKEvent]! { for i in eV { print("标题 \(i.title)" ) print("开始时间: \(i.startDate)" ) print("结束时间: \(i.endDate)" ) } } } }) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } }运行结果:
![](/blog_uploads/201610/2016100610451552273.png)
可不可以先教教我提醒怎么写?OC的我不太会翻译<( ̄3 ̄)>
这是添加事件,提醒怎么写呢?
EKEntityTypeEvent 已修改为EKEntityType.Reminder枚举
eventStore.saveEvent(event, span: EKSpanThisEvent, error: nil) 已修改为
do{
try eventStore.saveEvent(event, span: .ThisEvent)
}catch{
}