applejuiceteaching
applejuiceteaching

Reputation: 1493

Set a reminder in iOS Swift

I am trying to set a simple EKReminder in my swift application to remind users to catch the bus. However, when I try to save my reminder, I always get a error (no error is reported, the app just crashes). I have the code below.

public class func createReminder(reminderTitle: String, timeInterval:      NSDate) {
    var calendarDatabase = EKEventStore()

    calendarDatabase.requestAccessToEntityType(EKEntityTypeReminder,
        completion: nil)

    let reminder = EKReminder(eventStore: calendarDatabase)

    reminder.title = reminderTitle

    let alarm = EKAlarm(absoluteDate: timeInterval)

    reminder.addAlarm(alarm)

    reminder.calendar = calendarDatabase.defaultCalendarForNewReminders()

    var error: NSError?

    calendarDatabase.saveReminder(reminder, commit: true, error: &error)
}

Upvotes: 5

Views: 10913

Answers (3)

Mike Chirico
Mike Chirico

Reputation: 3491

The following should work in Swift 4.2

func AddReminder() {

 eventStore.requestAccess(to: EKEntityType.reminder, completion: {
  granted, error in
  if (granted) && (error == nil) {
    print("granted \(granted)")


    let reminder:EKReminder = EKReminder(eventStore: self.eventStore)
    reminder.title = "Must do this!"
    reminder.priority = 2

    //  How to show completed
    //reminder.completionDate = Date()

    reminder.notes = "...this is a note"


    let alarmTime = Date().addingTimeInterval(1*60*24*3)
    let alarm = EKAlarm(absoluteDate: alarmTime)
    reminder.addAlarm(alarm)

    reminder.calendar = self.eventStore.defaultCalendarForNewReminders()


    do {
      try self.eventStore.save(reminder, commit: true)
    } catch {
      print("Cannot save")
      return
    }
    print("Reminder saved")
  }
 })

}

info.plist requires appropriate privacy settings as well. enter image description here

Upvotes: 8

Sti
Sti

Reputation: 8503

I haven't used anything like this before, but looking at your code I can see that you call the requestAccessToEntity-method, without handling the response. That method will most likely show the user a prompt, asking them to accept that your app has access to "Reminders". With your code, you ask for the permission, but the rest of your code will execute immediately after asking, without 'waiting' for the response. The very first time this code runs, the user will be asked, and your reminder will be denied, because it tries to save right away. Even if your user clicks "allow", your code has already run without permission.

Now, if the user clicked allow one time, and then tries to do the same again, then maybe it will work, I don't know. But if your user clicked "Cancel" on the prompt, your code will never work until they go into Settings and allow your app to show reminders.

You should not create your reminder before you know if the user allows it, so you should really split this function into two separate functions. And do not pass nil for completion in that function; handle the response.

Upvotes: 0

claude Mad
claude Mad

Reputation: 11

try the following:

EKEntityTypeReminder -> EKEntityType.Reminder

Upvotes: -1

Related Questions