Search code examples
swiftnstimeruidatepicker

Select a time and execute code at that time


I am trying to add a feature where someone will select a time form a UIDatePicker. Once the current time and the time that is selected match up, code will be executed. This sounds fairly simple when typed out but my code is a mess.

I have tried to use a timer to update the code every second to see if the selected time matches the iPhones internal clock. This however has not worked successfully with my code. The code that i wrote set a timer in increments of 1 minute. If the time is 9:30:21 and you select 9:31, instead of the code executing at 9:31 it executes at 9:31:21. Here is my code, any help is greatly appreciated.

@IBAction func datePickerchanged(_ sender: Any) {
    setDateAndTime()
    check()
    timercount = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(check), userInfo: nil, repeats: true)
    _ = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(check), userInfo: nil, repeats: true)

    let clockString: String = formatADate()

    if str == clockString{
        takePhoto = true
    }
}


func update(_ currentTime: TimeInterval) {
    let clockString: String = formatADate()
    if str == clockString{
        takePhoto = true

    }
}
func refreshView () {
    let clockString: String = formatADate()
    if str == clockString{
        takePhoto = true
    }

}
func check() {
    let fireDate = datePicker.date

    if fireDate < Date() {
        takePhoto = true
    }
}

func setDateAndTime() {
    check()
    timercount = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(check), userInfo: nil, repeats: true)
    let formatter = DateFormatter()
    formatter.dateFormat = "hh:mm:ss a"
    _ = formatter.string(from: datePicker.date)
    str = dateFormatter.string(from: (datePicker?.date)!)
}
func formatADate() -> String {
    let dateFormatter = DateFormatter()
    dateFormatter.dateStyle = .short
    dateFormatter.dateFormat = "hh:mm:ss a"
    let date = NSDate()
    let output = dateFormatter.string(from: date as Date)
    print(output)
    return output
}

I tried using this code:

func check() {
        let fireDate = datePicker.date
        let timer = Timer(timeInterval: fireDate, target: self, selector: Selector(take), userInfo: 0, repeats: false)
        RunLoop.main.add(timer, forMode: RunLoopMode.commonModes)
        if fireDate < Date() {
            takePhoto = true
        }
    }
    func take() {
        takePhoto = true
    }

but i get an error cannot convert value type 'date' to expected argument type 'timeinterval' (aka 'double')


Solution

  • You can simply schedule a timer to fire at the date given by the picker.

    let timer = Timer(fireAt: fireDate, interval: 0, target: self, selector: #selector(<a selector you want to use...>), repeats: false)
    RunLoop.main.add(timer, forMode: RunLoopMode.commonModes)
    

    So, simply pass in the picker date in the "fireAt" parameter and the timer will fire at that date and run the selector you provide.