I'm building an app that allows the user to add and create events in the Calendar native app for iPhone. One of the features I'm working on is also to allow the user to add and create items in the Reminder's native app of the iPhone.
From what I've read, the Calendar and Reminders app work with EventKit, and from the documentation, the process of each don't differ too much.
I'm using this code to request permission to access Reminders and the code I use to add the items to the app.
Any thoughts on why is it not working? Thanks in advance.
import Foundation
import EventKit
class EventModel {
let eventStore = EKEventStore()
func requestAccessForReminders() {
let status = EKEventStore.authorizationStatus(for: .reminder)
if status == .authorized {
print("EKEventStore access for Reminders already granted.")
} else {
eventStore.requestFullAccessToEvents { success, error in
if success && error == nil {
print("EKEventStore access for Reminders has been granted.")
} else {
print("EKEventStore access for Reminders request failed with error: \(error?.localizedDescription ?? "Unknown error")")
}
}
}
}
func addEventToReminders(title: String, startHour: Int, startMinute: Int, duration: Int) -> Void {
let newEvent = EKReminder(eventStore: self.eventStore)
newEvent.title = title
newEvent.calendar = self.eventStore.defaultCalendarForNewReminders()
do {
try eventStore.save(newEvent,
commit: true)
} catch let error {
print("Reminder failed with error \(error.localizedDescription)")
}
}
}
This is the information I have in the info.plist. (I know is the same message, but that shouldn't be the main cause am I right?)
Your primary issue is that you are requesting access to the calendar, not to reminders. Use requestFullAccessToReminders
for iOS 17+ or requestAccess(to: .reminder)
for iOS 16- instead of requestFullAccessToEvents
.
Here's an updated version of your code that correctly requests access to reminders. This code handles iOS 17 as well as older versions of iOS. Obviously you need to call your requestAccessForReminders()
function before trying to add any reminders. It might be better to provide a completion handler for requestAccessForReminders
so you know when the request has completed.
class EventModel {
let eventStore = EKEventStore()
func requestAccessForReminders() {
let status = EKEventStore.authorizationStatus(for: .reminder)
switch status {
case .notDetermined:
func handleRequestCompletion(success: Bool, error: Error?) {
if let error {
print("Error trying to request access: \(error)")
} else if success {
print("User granted access")
} else {
print("User denied access")
}
}
if #available(iOS 17.0, *) {
eventStore.requestFullAccessToReminders { success, error in
handleRequestCompletion(success: success, error: error)
}
} else {
eventStore.requestAccess(to: .reminder) { success, error in
handleRequestCompletion(success: success, error: error)
}
}
case .restricted:
print("Restricted")
case .denied:
print("Denied") // Offer option to go to the app settings screen
case .fullAccess, .authorized: // fullAccess is for iOS 17+. authorized is for iOS 16-
print("Full access")
case .writeOnly:
print("Write-only access")
@unknown default:
print("Uh-oh, code is out-of-date")
}
}
func addEventToReminders(title: String, startHour: Int, startMinute: Int, duration: Int) -> Void {
let newEvent = EKReminder(eventStore: self.eventStore)
newEvent.title = title
newEvent.calendar = self.eventStore.defaultCalendarForNewReminders()
do {
try eventStore.save(newEvent, commit: true)
} catch let error {
print("Reminder failed with error \(error)")
}
}
}