-1

I am trying to read all calendar events from the EventStore. The routine I use, works sometimes but not always.

func getCalendarEvents(_ anfangOpt: Date?, _ endeOpt: Date?) -> [EKEvent]? {
    guard let anfang = anfangOpt, let ende = endeOpt else { return nil }
    var events: [EKEvent]? = nil
    let eventStore = EKEventStore()
    eventStore.requestAccess( to: EKEntityType.event, completion: { _,_ in })
    if EKEventStore.authorizationStatus(for: EKEntityType.event) == EKAuthorizationStatus.authorized {
        var predicate: NSPredicate? = nil
        predicate = eventStore.predicateForEvents(withStart: anfang, end: ende, calendars: nil)
        if let aPredicate = predicate {
            events = eventStore.events(matching: aPredicate)

        }
    }
    return events
}

This function always returns the events. But they are sometimes incomplete. So that

for event in bereinigteEvents {
    if dateInInterval(prüfdatum, start: event.startDate, ende: event.endDate) {
        istimurlaub = true
        if let zwischenname = event.title {
            eventname = zwischenname
        } else {
            eventname = "n/a"
        }
        eventcalendar = event.calendar.title
        trigger.append ("Auslöser: „" + eventname + "“ im Kalender „" + eventcalendar + "“")
    }
}

sometimes crashes at the line "eventcalendar = event.calendar.title" and the error message that "nil" was unexpectedly found.

Thank you!

After the first answer I have changed the function, which gets the events to:

func getCalendarEvents(_ anfangOpt: Date?, _ endeOpt: Date?) -> [EKEvent]? {

    guard let anfang = anfangOpt, let ende = endeOpt else { return nil }
    var events: [EKEvent]? = nil
    let eventStore = EKEventStore()

    func fetchEvents() {
        var predicate: NSPredicate? = nil
        predicate = eventStore.predicateForEvents(withStart: anfang, end: ende, calendars: nil)
        if let aPredicate = predicate {
            events = eventStore.events(matching: aPredicate)
        }
    }

    if EKEventStore.authorizationStatus(for: EKEntityType.event) == EKAuthorizationStatus.authorized {
        fetchEvents()
    } else {
        eventStore.requestAccess( to: EKEntityType.event, completion: {(granted, error) in
            if (granted) && (error == nil) {
                fetchEvents()
                }
        })
    }
    return events
}

But it still crashes with "unexpectedly found nil" in "event.calendar.title".

I ended up using this

Swift 4 How to get all events from calendar?

routine to fetch the events.

The problem still occurs sometimes (!!): Occasionally "nil" is found in "event.calender.title", although it shouldn't be "nil"

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Jan
  • 41
  • 5

2 Answers2

0

The line

eventStore.requestAccess( to: EKEntityType.event, completion: { _,_ in })

is pointless because it works asynchronously. The result of the request is returned after the authorizationStatus check in the next line.

I recommend to first check the status. If the access is not granted ask for permission and perform the fetch. If it's granted perform the fetch directly. This can be accomplished by moving the code to fetch the events into a method.

Note:

It seems that you want to fetch the events when calling the method. Why do you declare start and end date as optional and check for nil?

Declare

func getCalendarEvents(_ anfang: Date, _ ende: Date) -> [EKEvent]? { ...

then you get notified at compile time whether a parameter is nil.


PS: Deutsche Parameternamen mit Umlauten sehen sehr lustig aus. (German parameter names with umlauts look pretty funny)

vadian
  • 274,689
  • 30
  • 353
  • 361
  • Thanks. I have made the changes (see in the edit of my question), but it still crashes. – Jan Jan 29 '19 at 06:41
0

Problem was, that event.calendar is actually an optional (which I was not aware of).

if let eventZwischenCal = event.calendar {
    eventcalendar = eventZwischenCal.title
} else {
    eventcalendar = "n/a"
}

fixes the problem.

Dhaval Bhimani
  • 980
  • 1
  • 13
  • 24
Jan
  • 41
  • 5