0

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)
    }
}
halfer
  • 19,824
  • 17
  • 99
  • 186
Elfuthark
  • 261
  • 1
  • 4
  • 17
  • 1
    You should create the reminder in the completion handler after your request for access has completed successfully. – Paulw11 May 13 '17 at 22:02
  • Hi @Paulw11 I thought I had all my checks covered in my code. Can you see where I've gone wrong? – Elfuthark May 14 '17 at 09:37
  • The `requestAccess` completes asynchronously, so you need to call `createReminder` in the closure, after you print "access granted" – Paulw11 May 14 '17 at 09:52
  • @Paulw11 that worked a treat thank you but just one little nagging problem, for me to create a second reminder I have to fully close the app down and then reopen it for it to allow another reminder entry. Any Ideas? – Elfuthark May 14 '17 at 18:26
  • Sorry I was wrong this made my app run worse unfortunately and had to revert back – Elfuthark May 14 '17 at 20:53

1 Answers1

1

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) {
    ....
 }
Paulw11
  • 108,386
  • 14
  • 159
  • 186