Как запланировать уведомление в определенное время, а затем повторять его каждые x раз?

Я делаю приложение-напоминание, в котором вы можете запланировать напоминание, которое затем будет повторяться каждые x секунд/минут/часов/дней и т. д.

Если я хочу, чтобы это повторялось каждые x раз, я могу сделать это так:

func addNotification() {

let content = UNMutableNotificationContent()
content.title = "title"
// show this notification 5 minutes from now
var trigger: UNTimeIntervalNotificationTrigger
trigger = UNTimeIntervalNotificationTrigger(timeInterval: 300, repeats: true)
// choose a random identifier
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)

// add our notification request
UNUserNotificationCenter.current().add(request)

}

По сути, это то, что я хочу, но вместо того, чтобы начинать через 5 минут, я хочу иметь возможность выбрать дату начала, а затем повторять ее каждые 5 минут с этой начальной даты начала.

Это возможно?


person Peter Ruppert    schedule 28.10.2020    source источник
comment
Создайте объект Timer, настройте его интервал и повторяемость и добавьте его в основной цикл выполнения приложения. Вы также захотите рассмотреть возможность обработки событий, когда приложение входит в фоновый режим и выходит из него, поскольку таймер не останавливается и не приостанавливается.   -  person acidgate    schedule 28.10.2020
comment
Нет, это невозможно. Если вы установите repeats на true, минимальное значение timeInterval составит 1 минуту (60 секунд).   -  person Leo Dabus    schedule 28.10.2020
comment
@LeoDabus Извините, меня не волнуют 5 секунд, это был просто пример. Все мои варианты будут выше 5 минут, так что все в порядке. Я отредактирую вопрос.   -  person Peter Ruppert    schedule 28.10.2020
comment
Это не решается напрямую. Вам потребуется создать одноразовый триггер Calendar, а затем создать триггер TimeInterval, когда придет время. См. также stackoverflow.com/questions/41768342/   -  person Rob Napier    schedule 28.10.2020


Ответы (1)


Насколько я знаю, невозможно повторять уведомление каждые X секунд (или что-то еще) после определенной даты.

Я думаю, что лучший вариант здесь — использовать вместо этого UNCalendarNotificationTrigger и запланировать уведомление 60/5 = 12 (то есть 1 каждые 5 секунд), начиная с указанной даты.

Что-то вроде этого:

// this is your reference date - here it's now + 5 seconds just for this example
var referenceDate = Calendar.current.date(byAdding: .second, value: 5, to: Date())!
for i in 0...11 { // one every 5 seconds, so total = 12
    let content = UNMutableNotificationContent()
    content.title = "Notif \(i)"
    content.body = "Body"

    var dateComponents = DateComponents(calendar: Calendar.current)
    // 5 seconds interval here but you can set whatever you want, for hours, minutes, etc.
    dateComponents.second = 5
    //dateComponents.hour = X
    // [...]
    
    guard let nextTriggerDate = dateComponents.calendar?.date(byAdding: dateComponents, to: referenceDate),
          let nextTriggerDateCompnents = dateComponents.calendar?.dateComponents([.second], from: nextTriggerDate) else {
        return
    }
    referenceDate = nextTriggerDate

    print(nextTriggerDate)
    let trigger = UNCalendarNotificationTrigger(dateMatching: nextTriggerDateCompnents, repeats: true)
    let request = UNNotificationRequest(identifier: "notif-\(i)", content: content, trigger: trigger)
    UNUserNotificationCenter.current().add(request)
}

Теперь, исходя из этого, вам нужно будет обрабатывать, когда пользователь нажимает на одно из уведомлений, чтобы отменить все остальные. Но это уже другая тема, и я оставляю на ваше усмотрение найти логику для этого.

person mxlhz    schedule 28.10.2020