我使用的是Swift 4.1。我想写一个函数,它将收集iOS日历应用程序中所有日历中的所有事件。多亏了stackoverflow上的这个答案:如何从日历中获取所有事件(Swift(我能够编写自己的class
并称之为Cale
。请看这个:
import UIKit
import EventKit
class Cale {
private func createDate(year: Int) -> Date {
var components = DateComponents()
components.year = year
components.timeZone = TimeZone(secondsFromGMT: 0)
return Calendar.current.date(from: components)!
}
private let eventStore = EKEventStore()
private func get() {
let calendars = eventStore.calendars(for: .event)
for calendar in calendars {
// This checking will remove Birthdays and Hollidays callendars
guard calendar.allowsContentModifications else {
continue
}
let start = createDate(year: 2016)
let end = createDate(year: 2025)
print("start: (start)")
print(" end: (end)")
let predicate = eventStore.predicateForEvents(withStart: start, end: end, calendars: [calendar])
print("predicate: (predicate)")
let events = eventStore.events(matching: predicate)
for event in events {
print(" title: (event.title!)")
print("startDate: (event.startDate!)")
print(" endDate: (event.endDate!)")
}
}
}
func checkStatusAndGetAllEvents() {
let currentStatus = EKEventStore.authorizationStatus(for: EKEntityType.event)
switch currentStatus {
case .authorized:
//print("authorized")
self.get()
case .notDetermined:
//print("notDetermined")
eventStore.requestAccess(to: .event) { accessGranted, error in
if accessGranted {
self.get()
} else {
print("Change Settings to Allow Access")
}
}
case .restricted:
print("restricted")
case .denied:
print("denied")
}
}
}
非常简单的类,你可以使用它,它正在工作,但有一个例外。这里的主要函数是get()
。在这个函数中,我基于两个日期创建谓词:开始和结束。正如你所看到的,开始日期是:
2016-01-01 00:00:00+0000
,结束日期为:
2025-01-01 00:00:00+0000
但如果我们运行程序,我们会看到谓词将是这样的:
CADEventPredicate开始时间:2016年1月1日03:00;结束时间:2020年1月1日03:00;cals:(2(
仅从2016年到2020年,4年!我在不同的日期测试过它,但我可以得到最长间隔4年的谓词。这意味着,它不会给我所有的事件!所以问题是:如何从日历中获取所有事件?如果可能的话,不用日期!
感谢您将来的任何帮助或建议!
如果有人还在想,苹果有意将这一期限限制在四年内。
来自事件预测(带开始:结束:日历:(:
出于性能原因,此方法只匹配四年时间跨度内的那些事件。如果startDate和endDate之间的日期范围大于四年,则会缩短为前四年。
如果你想要一个比这个更长的范围,我想你必须把它包装在你自己的函数中,把它分成四年的块。
花了这么多时间,我找到了问题的解决方案。我的问题如下,
event start date 2019-03-15 09:00:00 +0000
event end date 2019-03-15 14:00:00 +0000
谓词如下,
CADEventPredicate start:15/03/19, 1:30 PM; end:15/03/19, 7:30 PM; cals:(null)
由于我来自印度,谓词是将GMT+5:30添加到我的实际事件开始和结束时间。我从堆栈溢出中得到了一个方法,将其转换为local&全球时区如下。
extension Date {
// Convert local time to UTC (or GMT)
func toGlobalTime() -> Date {
let timezone = TimeZone.current
let seconds = -TimeInterval(timezone.secondsFromGMT(for: self))
return Date(timeInterval: seconds, since: self)
}
// Convert UTC (or GMT) to local time
func toLocalTime() -> Date {
let timezone = TimeZone.current
let seconds = TimeInterval(timezone.secondsFromGMT(for: self))
return Date(timeInterval: seconds, since: self)
}
}
在将开始和结束日期与时间一起传递给谓词时,我将转换为globalTimeZone,如下所示。
let predicate = eventStore.predicateForEvents(withStart: eventStartDateTime.toGlobalTime(), end: eventEndDateTime.toGlobalTime(), calendars: nil)
如果你没有时间,你只有开始&结束日期,然后使用下面的谓词,
event start date 2019-03-15 00:00:00 +0000
event end date 2019-03-15 00:00:00 +0000
let predicate = eventStore.predicateForEvents(withStart: eventStartDateTime, end: eventEndDateTime, calendars: nil)
因为如果你没有时间转换到globalTimeZone,你可能会在删除事件时遇到问题。
我希望它能帮助一些人。