0

I am trying to set up daily repeated notifications with swift.

I am able to set up the notification by using

var dateComponents = DateComponents()
dateComponents.hour = 17
dateComponents.minute = 00

But I want the user to be able to change that, I set up a date picker and changed it to time only

In the date picker I was able to get it to save by doing the following

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    loadDate(animation: true)
}

func saveDate() {
    UserDefaults.standard.set(TimePicker.date, forKey:dateKey)
}

func loadDate(animation: Bool) {
    guard let loadedDate = UserDefaults.standard.object(forKey: dateKey) as? NSDate else { return }

    TimePicker.setDate(loadedDate as Date, animated: animation)
}

How can I pass what was selected from hour and minute to the notification time? Also how would I be able to convert the time to 24 hours that way if they select 5 pm it goes to the date component as 17?

Thanks for any help

This is how I have the view controller. inside viewdidload. and then the timepicker is inside another viewcontroller

let center = UNUserNotificationCenter.current()

center.requestAuthorization(options: [.alert, .sound ]){(grandted,error)in }


let content = UNMutableNotificationContent()
content.title = "Title"
content.body = "Body"

var dateComponents = DateComponents()
dateComponents.hour = 17
dateComponents.minute = 18

let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)


let uuidstring = UUID().uuidString

let request = UNNotificationRequest(identifier: uuidstring, content: content, trigger: trigger)

center.add(request) {(error) in}
ManWithBear
  • 2,787
  • 15
  • 27
YT32Z
  • 3
  • 2

1 Answers1

0

Since you dong time selection on another view controller (second), you need to notify first (main) view controller that date have been changed.

Here many different ways to do it. Passing Data between View Controllers
Choose any you like, for this example I will use notifications:

extension Notification.Name {
    /// Notification used to pass user selected date
    static let dateChanged = Notification.Name(rawValue: "DateChanged")
}

In second controller update save function:

func saveDate() {
    UserDefaults.standard.set(TimePicker.date, forKey:dateKey)
    /// Send notification with new time
    NotificationCenter.default.post(name: .dateChanged, object: TimePicker.date)
}

In same time in main controller you need to subscribe to notifications:

deinit {
    /// We need to unsubscribe from notifications, otherwise app can crash
    NotificationCenter.default.removeObserver(self)
}

override func viewDidLoad() {
    super.viewDidLoad()
    ...
    /// Subscribe to notifications 
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(dateChanged(_:)),
        name: .dateChanged,
        object: nil
    )
}

/// This method will be called when controller receive notification
/// It need to be annotated with @objc
@objc func dateChanged(_ notification: Notification) {
    let date = notification.object as! Date
    let components = Calendar.current.dateComponents([.hour, .minute], from: date)
    setNotification(with: components)
}

/// By always using same ID for local notifications 
/// You can easily remove them when time changes
private static let notificationID = "MyAppNotificationID"

func setNotification(with components: DateComponents) {
    /// Remove previously planned notification
    center.removePendingNotificationRequests(withIdentifiers: [MainVC.notificationID])

    /// Create new notificaion
    let content = UNMutableNotificationContent()
    content.title = "Title"
    content.body = "Body"
    let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)
    let request = UNNotificationRequest(identifier: MainVC.notificationID, content: content, trigger: trigger)

    /// Add to center
    center.add(request) {(error) in}
}
ManWithBear
  • 2,787
  • 15
  • 27
  • Can't seem to get it to work anymore like that, for the trigger I still have it as dateComponents how would i replace it to user timepicker? Thanks a lot for the help – YT32Z Mar 24 '19 at 00:08
  • @YT32Z please show how you create notification request – ManWithBear Mar 24 '19 at 00:09
  • @ManWinBear. I edited the post and showed how the notification was set up. I have it inside the main view controller and then I have the date picker insider another view controller. I can put them in the same one if needed, but if I can call the function from another view it might be better. I am really new to swift so I am not sure on how to go about doing this. Also would this keep a deafult time? Thanks again – YT32Z Mar 24 '19 at 02:00
  • @ManWinBear Thank you so much for the help I really appreciate it that worked perfectly! You are the man – YT32Z Mar 24 '19 at 03:20