Swift 4如何从日历中获取所有活动?

问题描述 投票:2回答:1

我正在使用Swift 4.1。我想编写一个函数来收集iOS日历应用程序中所有日历的所有事件。感谢stackoverflow上的这个答案: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")
        }
    }
}

相当简单的类,你可以使用它,它工作但有一个例外。主要功能是get()在这个函数中我基于两个日期创建谓词:开始和结束。如您所见,开始日期是:

2016-01-01 00:00:00 +0000

和结束日期是:

2025-01-01 00:00:00 +0000

但是如果我们运行该程序,我们将看到谓词将是这样的:

CADEventPredicate开始时间:01/01/2016,03:00;结束:01/01 / 201,03:00; cals:(2)

仅从2016年到2020年,4年!我已经在不同的日期对它进行了测试,但我可以获得最长4年的谓词。这意味着,它不会给我所有的活动!所以问题是:如何从日历中获取所有事件?如果可能的话,不使用日期!

感谢您以后的任何帮助或建议!

ios swift calendar eventkit ekcalendar
1个回答
0
投票

花了这么多时间后,我找到了解决问题的方法。我的问题如下,

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,则可能在删除事件时遇到问题。

我希望它会帮助一些人。

© www.soinside.com 2019 - 2024. All rights reserved.