I'm new to EventKit and EventKitUI and trying to figure out how to extract the event start and stop timing from an event created within an iOS 17 app with an EventEditViewController. I pass proposed timing into the EventEditViewController, but the user may modify the timing. Note that I'm not looking to read events directly from the user's calendar - I just want to know if the user created the proposed calendar event and the timing of that event. Is this possible without requesting full read-write access to a user's calendar? I've attached my code below - what I'm trying to do is update the ViewModel calendarEventUsed, eventStartDate, and eventStopDate properties with information from the EventEditViewController calendarEventCreated property and EKEvent timing. My attempts to do this from within the eventEditViewController didCompleteWith function throw an error.
import Foundation
import SwiftUI
@Observable class ViewModel {
var name: String = "Test item"
// MARK: - Calendar Event Properties
var calendarEventUsed: Bool = false
var eventStartDate: Date = Date()
var eventEndDate: Date = Date()
}
import SwiftUI
struct ContentView: View {
@State var viewModel = ViewModel()
@State private var showEventEditViewController = false
static let dateFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.timeStyle = .medium
return dateFormatter
}()
var body: some View {
NavigationStack {
Form {
Section(header: Text("Apple Calendar Event")) {
Button {
var eventStartDateComponents = Calendar.current.dateComponents([Calendar.Component.hour, Calendar.Component.day, Calendar.Component.month, Calendar.Component.year], from: viewModel.eventStartDate)
eventStartDateComponents.minute = 0 // Clean up the timing
viewModel.eventStartDate = Calendar.current.date(from: eventStartDateComponents)!
viewModel.eventEndDate = Calendar.current.date(byAdding: .hour, value: 1, to: viewModel.eventStartDate)!
self.showEventEditViewController.toggle()
} label: {
HStack {
Spacer()
Text("Create calendar event")
Spacer()
} // End of HStack
} // End of button
HStack {
Text("calendarEventUsed")
Spacer()
Text(String(viewModel.calendarEventUsed))
}
HStack {
Text("eventStartDate")
Spacer()
Text(viewModel.eventStartDate, formatter: Self.dateFormatter)
}
} // End of Calendar Event
} // End of Form
.navigationBarTitle("New Item", displayMode: .inline)
} // End of NavigationStack
.sheet(isPresented: $showEventEditViewController) {
EventEditViewController(title: viewModel.name,
startDate: $viewModel.eventStartDate,
endDate: $viewModel.eventEndDate)
}
} // End of body
}
import Foundation
import SwiftUI
import EventKit
import EventKitUI
struct EventEditViewController: UIViewControllerRepresentable {
@Environment(\.presentationMode) var presentationMode
typealias UIViewControllerType = EKEventEditViewController
var title: String
@Binding var startDate: Date
@Binding var endDate: Date
var calendarEventCreated: Bool = false
private let eventStore = EKEventStore()
private var event: EKEvent {
let possibleEvent = EKEvent(eventStore: eventStore)
possibleEvent.title = title
possibleEvent.startDate = startDate
possibleEvent.endDate = endDate
print("possibleEvent.startDate= \(String(describing: possibleEvent.startDate))")
return possibleEvent
}
func updateEventDetails() {
self.startDate = event.startDate
self.endDate = event.endDate
}
/// Create an event edit view controller, then configure it with the specified event and event store.
func makeUIViewController(context: Context) -> EKEventEditViewController {
let controller = EKEventEditViewController() // initialize the event edit view controller
controller.eventStore = eventStore // specify the eventStore created in a separate script in Step #1
controller.event = event // specify the optional event defined above and passed into the EKEventEditViewController as a @Binding
controller.editViewDelegate = context.coordinator // assigns the coordinator (below) as the delegate
print("controller.event!.startDate = \(String(describing: controller.event!.startDate))")
return controller
}
func updateUIViewController(_ uiViewController: EKEventEditViewController, context: Context) {
}
func makeCoordinator() -> Coordinator {
return Coordinator(self)
}
class Coordinator: NSObject, EKEventEditViewDelegate {
var parent: EventEditViewController
init(_ controller: EventEditViewController) {
self.parent = controller
}
func eventEditViewController(_ controller: EKEventEditViewController, didCompleteWith action: EKEventEditViewAction) {
parent.presentationMode.wrappedValue.dismiss()
if action == .saved { trying to modify the startDate and endDate per user input...
parent.calendarEventCreated = true
print("parent.calendarEventCreated = \(parent.calendarEventCreated)")
print("parent.startDate = \(parent.startDate)")
// updateEventDetails()
// parent.startDate = event.startDate // Instance member 'event' of type 'EventEditViewController' cannot be used on instance of nested type 'EventEditViewController.Coordinator'
}
}
}
}