1

I'm working on an app in Swift/SwiftUI that displays calendar events from a calendar on the user's device called "All Classes". Details about each event within that calendar should appear in TodayView. To be clear, the app should only display events from the current day.

I should note that I'm very new to Swift/SwiftUI.

This is what I've tried so far. As expected, the app requests permission to access the calendar, but no events are displayed on-screen. I have not limited the code to searching the "All Classes" calendar simply because I do not know how. Would anyone be able to help? Thanks!

import SwiftUI
import EventKit
import EventKitUI

let eventStore = EKEventStore()
var events : [EKEvent] = []

struct TodayView: View {
    init() {
        events = getEvents()
    }
    
    var body: some View {
        NavigationView {
            ZStack {
                background
                ScrollView (.vertical) {
                    VStack {
                        ForEach(events, id :\.self) { event in
                            Text(event.title)
                        }
                    }
                }
            }
            .navigationTitle("Today")
        }
    }
}

func getEvents() -> [EKEvent] {
    var eventList : [EKEvent] = []
    eventStore.requestAccess(to: .event) { (granted, error) in
        if granted {
            DispatchQueue.main.async {
                let predicate = eventStore.predicateForEvents(withStart: Date().dayBefore, end: Date().dayAfter, calendars: nil)
                
                let events = eventStore.events(matching: predicate)
                
                for e in events {
                    eventList.append(e)
                }
            }
        }
    }
    return eventList
}

extension Date {
    var dayBefore: Date {
        return Calendar.current.date(byAdding: .day, value: -1, to: self)!
    }
    
    var dayAfter : Date {
        return Calendar.current.date(byAdding: .day, value: 1, to: self)!
    }
}
  • The `eventStore.requestAccess` method is async and you are fetching the events from its completion handler. So the `return eventList` is executed before `requestAccess` could call its completion handler and hence `eventList` is never mutated to contain the fetched events. The linked duplicate clearly explains how to handle asynchronous methods in a synchronous context. – Dávid Pásztor Jun 06 '23 at 16:06
  • Ok, thanks for your help! Even reading the linked duplicate, I’m still having trouble applying what’s there to my code. Do you have any suggestions? – Tanner George Jun 06 '23 at 16:37

0 Answers0