Swift 4 如何从日历中获取所有事件?
Swift 4 How to get all events from calendar?
我正在使用 Swift 4.1。我想编写一个函数来收集 iOS 日历应用程序中所有日历的所有事件。感谢 Whosebug 上的这个答案:How to get all Events out of a Calendar (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")
}
}
}
很简单class,你可以使用它,它可以工作,但有一个例外。
主要功能是 get()
在此功能中,我基于两个日期创建谓词:开始和结束。如您所见,开始日期为:
2016-01-01 00:00:00 +0000
结束日期为:
2025-01-01 00:00:00 +0000
但是如果我们运行程序我们会看到谓词是这样的:
CADEventPredicate start:01/01/2016, 03:00; end:01/01/2020, 03:00;
cals:(
2 )
才2016年到2020年,4年!我已经在不同的日期对其进行了测试,但我可以获得最大间隔为 4 年的谓词。这意味着,它不会给我所有事件!所以问题是:如何从日历中获取所有事件?如果可能,不使用日期!
感谢您以后的任何帮助或建议!
花了这么多时间后,我找到了解决问题的方法。我的问题如下,
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 添加到我的实际事件开始和结束时间。我从堆栈溢出中得到一个方法,如下所示转换为本地和全球时区。
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,您可能会在删除事件时遇到问题。
希望对大家有所帮助。
如果有人仍然想知道,Apple 有意将此限制为四年。
来自predicateForEvents(withStart:end:calendars:):
For performance reasons, this method matches only those events within a four year time span. If the date range between startDate and endDate is greater than four years, it is shortened to the first four years.
如果你想要一个比这更长的范围,我想你必须将它包装在你自己的函数中以将它分成四年的块。
我正在使用 Swift 4.1。我想编写一个函数来收集 iOS 日历应用程序中所有日历的所有事件。感谢 Whosebug 上的这个答案:How to get all Events out of a Calendar (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")
}
}
}
很简单class,你可以使用它,它可以工作,但有一个例外。
主要功能是 get()
在此功能中,我基于两个日期创建谓词:开始和结束。如您所见,开始日期为:
2016-01-01 00:00:00 +0000
结束日期为:
2025-01-01 00:00:00 +0000
但是如果我们运行程序我们会看到谓词是这样的:
CADEventPredicate start:01/01/2016, 03:00; end:01/01/2020, 03:00; cals:( 2 )
才2016年到2020年,4年!我已经在不同的日期对其进行了测试,但我可以获得最大间隔为 4 年的谓词。这意味着,它不会给我所有事件!所以问题是:如何从日历中获取所有事件?如果可能,不使用日期!
感谢您以后的任何帮助或建议!
花了这么多时间后,我找到了解决问题的方法。我的问题如下,
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 添加到我的实际事件开始和结束时间。我从堆栈溢出中得到一个方法,如下所示转换为本地和全球时区。
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,您可能会在删除事件时遇到问题。
希望对大家有所帮助。
如果有人仍然想知道,Apple 有意将此限制为四年。
来自predicateForEvents(withStart:end:calendars:):
For performance reasons, this method matches only those events within a four year time span. If the date range between startDate and endDate is greater than four years, it is shortened to the first four years.
如果你想要一个比这更长的范围,我想你必须将它包装在你自己的函数中以将它分成四年的块。