I’m updating my localnotifications to work with iOS 10 and I’ve run into an issue where I think the nextTrigger function returns NOT “The next date at which the trigger conditions will be met.” but instead returns whatever the current date time is PLUS what you had initially set the UNTimeInvervalNotificationTrigger to.
So if you set the trigger to go off in 60 seconds, from the documentation I expect that when I call the nextTriggerDate() that I’d get it to return whatever the date time is when I set the trigger + 60 seconds. So if I set it at 12:00:00, I’d expect that the nextTriggerDate() would be 12:01:00. However what I’m experiencing is that it returns whatever the current date is + 60 seconds.
I wrote a sample that schedules a UNTimeIntervalNotificationTrigger and then prints out the nextTriggerDate() every second. When I run this I get a new nextTriggerDate every second. Like this:
//Optional(2016-11-03 21:26:31 +0000)
//Optional(2016-11-03 21:26:32 +0000)
//Optional(2016-11-03 21:26:33 +0000)
//Optional(2016-11-03 21:26:34 +0000)
//Optional(2016-11-03 21:26:35 +0000)
//Optional(2016-11-03 21:26:36 +0000)
I’ve opened a TSI with apple but… you know… that takes awhile. So I thought I’d see if anyone here had any insight. I suspect it’s a bug and if I get more information I’ll update this.
This is the code I’ve used to illustrate the issue:
import UIKit
import UserNotifications
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
@IBOutlet weak var setButton: UIButton!
@IBOutlet weak var timePicker: UIPickerView!
weak var timer: Timer?
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func setButtonAction(_ sender: UIButton) {
var mySecond = pickerSelection
// build notification
let content = UNMutableNotificationContent()
content.title = "Title of notification"
content.body = "This is the body of the notification"
content.sound = UNNotificationSound.default()
content.categoryIdentifier = "myCategory"
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: Double(mySecond), repeats: false)
let request = UNNotificationRequest(identifier: "test notification", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) {(error) in
if let error = error {
print("Uh oh! We had an error: \(error)")
}
}
self.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.tick), userInfo: nil, repeats: true)
}
let pickerData = [":00",":01",":02",":03",":04",":05",":06",":07",":08",":09",":10",":11",":12",":13",":14",":15",":16",":17",":18",":19",":20",":21",":22",":23",":24",":25",":26",":27",":28",":29",":30",":31",":32",":33",":34",":35",":36",":37",":38",":39",":40",":41",":42",":43",":44",":45",":46",":47",":48",":49",":50",":51",":52",":53",":54",":55",":56",":57",":58",":59"]
var pickerSelection = 0
override func viewDidLoad() {
super.viewDidLoad()
self.timePicker.dataSource = self
self.timePicker.delegate = self
self.timePicker.selectRow(pickerSelection, inComponent: 0, animated: false)
}
// The number of columns of data
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
// The number of rows of data
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerData.count
}
// The data to return for the row and component (column) that's being passed in
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return pickerData[row]
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
let pickerLabel = UILabel()
let titleData = pickerData[row]
let myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Futura", size: 44.0)!])
pickerLabel.attributedText = myTitle
pickerLabel.textAlignment = .center
return pickerLabel
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
pickerSelection = row
}
func tick() {
let center = UNUserNotificationCenter.current()
center.getPendingNotificationRequests(completionHandler: { (scheduledLocalNotifications) in
for localNotice in scheduledLocalNotifications {
var localTrigger = localNotice.trigger as! UNTimeIntervalNotificationTrigger
var localTime = localTrigger.nextTriggerDate()
// ** This output shows something like this:
//Optional(2016-11-03 21:26:31 +0000)
//Optional(2016-11-03 21:26:32 +0000)
//Optional(2016-11-03 21:26:33 +0000)
//Optional(2016-11-03 21:26:34 +0000)
//Optional(2016-11-03 21:26:35 +0000)
//Optional(2016-11-03 21:26:36 +0000)
print("\(localTime)")
}
})
}
}
Heard back from Apple DTS and was told that the functionality I'd described was how it was designed to work. Although I had thought the documentation explained it differently they told me that "the documentation was optimistic given the implementation." Anyway, I worked around it by keeping track of the fire date in my code. I hope this answer can help someone else who had the same problem I did.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With