Search code examples
iosswifteventkitreminders

Sending data (label and date picker) from my app to the Reminders app


I've created an appointment reminder section in my app but it seems the first use of the app doesn't get stored? When I click the create reminder button I get my popup alert saying it was successfully created followed by the would like to access your reminders popup. Because of this people's first appointments aren't being stored, and I can't figure out what I have done wrong?

Here is my code:

import UIKit
import EventKit

class FirstViewController: UIViewController {

    @IBOutlet weak var reminderText: UITextField!
    @IBOutlet weak var myDatePicker: UIDatePicker!
    let appDelegate = UIApplication.shared.delegate
        as! AppDelegate

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

    }

    @IBAction func setReminder(_ sender: AnyObject) {

        if reminderText.text == "" {

            // Create the alert controller
            let alertController = UIAlertController(title: "Information Needed", message: "Please type in your treatment and select the correct date and time you wish to be reminded about before pressing the Create Appointment Reminder button.", preferredStyle: .alert)

            // Create the actions
            let okAction = UIAlertAction(title: "Got It", style: UIAlertActionStyle.default) {
                UIAlertAction in
                NSLog("OK Pressed")
            }

            // Add the actions
            alertController.addAction(okAction)

            // Present the controller
            self.present(alertController, animated: true, completion: nil)

        } else {

            if appDelegate.eventStore == nil {
                appDelegate.eventStore = EKEventStore()
                appDelegate.eventStore?.requestAccess(
                    to: EKEntityType.reminder, completion: {(granted, error) in
                        if !granted {
                            print("Access to store not granted")
                            print(error!.localizedDescription)
                        } else {
                            print("Access granted")
                        }
                })
            }

            if (appDelegate.eventStore != nil) {
                self.createReminder()
            }
        }

        self.reminderText.resignFirstResponder()

    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {

        textField.resignFirstResponder()

        return true

    }

    func createReminder() {

        let reminder = EKReminder(eventStore: appDelegate.eventStore!)

        reminder.title = reminderText.text! + " " + "(Pose Beauty Salon)"
        reminder.calendar =
            appDelegate.eventStore!.defaultCalendarForNewReminders()
        let date = myDatePicker.date
        let alarm = EKAlarm(absoluteDate: date)

        reminder.addAlarm(alarm)

        do {
            try appDelegate.eventStore?.save(reminder,
                                             commit: true)
        } catch let error  {
            print("Reminder failed with error \(error.localizedDescription)")
        }

        // Create the alert controller
        let alertController = UIAlertController(title: "Reminder Created Successfully", message: "Your \(reminderText.text!) appointment reminder at Pose Beauty Salon has been successfully created in your iPhone Reminders app.  Thank You! ", preferredStyle: .alert)

        // Create the actions
        let okAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.default) {
            UIAlertAction in
            NSLog("OK Pressed")
        }

        // Add the actions
        alertController.addAction(okAction)

        // Present the controller
        self.present(alertController, animated: true, completion: nil)

        reminderText.text = ""
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        reminderText.endEditing(true)
    }
}

Solution

  • Your logic is much more complicated than it needs to be. You can take advantage of the fact that when you request access to the event store after access has already been granted (or denied) then those permissions are used without prompting the user.

    It is also poor form to initialise a property of the AppDelegate from some other class. You probably don't even need the EventStore on the AppDelegate - you can just create an instance when you need it.

    You can use something like:

    } else {
        let eventStore = EKEventStore()
        eventStore.requestAccess(
                    to: EKEntityType.reminder, completion: {(granted, error) in
            if !granted {
                print("Access to store not granted")
                print(error!.localizedDescription)
            } else {
                print("Access granted")
                self.createReminder(in: eventStore)
            }
        })
    }
    
    
     func createReminder(in eventStore: EKEventStore) {
        ....
     }