#swift #timer #notifications #intervals #reminders
#swift #таймер #уведомления #интервалы #напоминания
Вопрос:
Пример (я пытаюсь создать что-то вроде этого. Теперь вы можете видеть, здесь вы можете выбрать время и интервал)
Я создал напоминание, в котором пользователь может выбирать, как часто получать уведомления (каждые 2 дня, каждые 3 дня и т.д.), Но я также хочу, чтобы пользователь мог выбирать время. Я знаю, как создать напоминание, которое будет отправлять уведомления в выбранное время, но я должен использовать UNCalendarNotificationTrigger
, и проблема в том, что я использую UNTimeIntervalNotificationTrigger
. Спасибо
@IBOutlet weak var picker: UIPickerView!
@IBOutlet weak var timePicker: UIDatePicker!
@IBAction func setReminderBtnTapped(_ sender: Any) {
let content = UNMutableNotificationContent()
content.title = "Test"
content.body = "Blablabla"
content.sound = .default
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: TimeInterval((picker.selectedRow(inComponent: 1) 1)*(24*3600)), repeats: true)
let request = UNNotificationRequest(identifier: "blabla.reminder", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { (error) in
if let error = error {
print("error")
}
}
print("Notification added")
}
Ответ №1:
попробуйте этот код:
private func setLocalNotification(hour: Int, minute: Int, completionHandler: @escaping (Bool) -> Void) {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .badge, .sound]) { [weak self] (granted, error) in
guard let self = self else {
return
}
let center = UNUserNotificationCenter.current()
center.removeAllPendingNotificationRequests()
guard error == nil else {
completionHandler(false)
return
}
if granted {
let content = UNMutableNotificationContent()
content.title = "title"
content.sound = UNNotificationSound.default
content.badge = 1
var dateComponents = DateComponents()
dateComponents.hour = hour
dateComponents.minute = minute
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
center.add(request)
completionHandler(true)
return
}
completionHandler(false)
}
}
и вы можете вызвать, получив дату из DatePicker следующим образом:
let date = self.timepPicker.date
let calendar = Calendar.current
let hour = calendar.component(.hour, from: date) // get hour
let minutes = calendar.component(.minute, from: date) // get minute
self.setLocalNotification(hour: hour, minute: minutes) { [weak self] isSet in
guard let self = self else {
return
}
if !isSet {
let center = UNUserNotificationCenter.current()
center.removeAllPendingNotificationRequests() // remove previus notification
}
}
обновляйте ответ для
повторения X раз в каждый n день:
создать расширение из date для создания простых компонентов date getDateComponents:
extension Date {
public func getDateComponents() -> DateComponents {
let dateComponents = Calendar.current.dateComponents([.hour, .minute, .second, .day], from: self)
return dateComponents
}
}
и обновите функцию setLocalNotification:
private func setLocalNotification(repeatCount: Int, jumpNextDay: Int, hour: Int, minute: Int) {
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
let center = UNUserNotificationCenter.current()
center.removeAllPendingNotificationRequests()
guard error == nil else {
return
}
if granted {
let content = UNMutableNotificationContent()
content.title = "title"
content.sound = UNNotificationSound.default
content.badge = 1
// create date from hour and minute based on current
let firstDate = Calendar.current.date(bySettingHour: hour, minute: minute, second: 0, of: Date())!
let firstTimeInterval = firstDate.timeIntervalSince1970 // get timeInterval
// example run for
// repeat count 5 and jump 2
// 2 4 6 8 10
for i in stride(from: jumpNextDay, to: jumpNextDay * (repeatCount 1), by: jumpNextDay) {
// create next day
// 86400 next time interval added to first time interval
// create time interval from first date
// 2 next day = firstTimeInterval 2 * 86400
let timeIntervalForTrigger = firstTimeInterval Double((i * 86400))
// create date from time interval
let date = Date.init(timeIntervalSince1970: timeIntervalForTrigger)
// create datecomponnet
let dateComponents = date.getDateComponents()
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
center.add(request)
}
}
}
}
и позвонить:
let date = self.timepPicker.date
let calendar = Calendar.current
let hour = calendar.component(.hour, from: date) // get hour
let minutes = calendar.component(.minute, from: date) // get minute
self.setLocalNotification(repeatCount: 2, jumpNextDay: 2, hour: hour, minute: minutes)
Комментарии:
1. Извините, ваш код работает, но когда я меняю интервал (количество дней, как часто получать уведомления), уведомления приходят каждый день. Так работает или по дням, или по времени, но я стараюсь совместить две вещи. Например, настройте уведомления каждые X дней (которые я выбираю с помощью средства выбора) в X время (которое я также выбираю с помощью средства выбора). В этом и заключается проблема. 🙁 потому что, если я выбираю интервал, я использую UNTimeIntervalNotificationTrigger, если я выбираю время, я использую UNCalendarNotificationTrigger
2. добавьте новый подход к моему ответу, посмотрите еще раз
3. Да, это работает, уведомления приходят каждые 2 дня и повторяются 2 раза, как в этой строке (self.setLocalNotification(repeatCount: 2, jumpNextDay: 2, час: час, минута: минуты)) в то время, которое я выбрал из TimePicker. Но у меня также есть другой сборщик для интервала, поэтому я не понимаю, как я могу сделать «jumpNextDay» из сборщика и повторять его бесконечно … p.s. Я новичок, поэтому прошу прощения, если я не понимаю простых вещей
4. Если вы хотите, вы можете отправить пользовательский интерфейс, который вам нужно реализовать вместе с рабочим процессом, здесь, чтобы я мог вам помочь.
5. Я обновил свой вопрос и добавил фотографию 🙂