Прежде чем я начну, пожалуйста, не сжигайте меня, так как я знаю, что об этом уже сотни раз спрашивали без надежного ответа, но я считаю, что есть решение, использующее фоновое обновление. https://medisafe.com/ приложение, похоже, решило эту проблему!
Цель:
Для запуска локального уведомления в указанное время каждые x дней
Мое решение
шаг 1: получить интервал таймера от даты начала и нечетного появления (в данном случае 2) дней от (отредактировано)
шаг 2: установить интервал таймера на эту разницу с повтором
шаг 3: активировать фоновое обновление (если приложение даже будет закрыто, оно загрузит приложение в фоновом режиме и даст мне небольшое окно для выполнения некоторых задач)
шаг 4. установить фоновое обновление, чтобы запускаться один раз в день
шаг 5: выполните API-интерфейсы get items, которые обновят все таймеры и уведомления
шаг 6 сядь и с удивлением улыбаюсь моему решению
но это не удалось.
так, интервал таймера
let newTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 172800,repeats: true)
, но это будет просто сбрасывать таймер каждый день, когда выполняется фоновая выборка, и будет запускаться через 2 дня с СЕЙЧАС, а не с даты начала.
Таким образом, должен быть способ сравнения дат, часов и минут (дата начала, дата x и текущая дата, чтобы определить значение интервала таймера.
В настоящее время я использую компоненты календаря. чтобы вызвать каждый день, я делаю следующее
var triggerType : DateComponents? {
var triggerT : DateComponents?
var cal = Calendar(identifier: .gregorian)
cal.firstWeekday = 2
if let notificationModel = self.notificationModel {
switch notificationModel.reminderType {
case .daily?, .weekly?:
if let date = notificationModel.date {
triggerT = cal.dateComponents([.weekday, .hour, .minute], from:date)
if let weekday = notificationModel.weekday {
triggerT?.weekday = weekday
}
}
case .alternateDays?:
if let date = notificationModel.date {
triggerT = cal.dateComponents([ .hour, .minute], from:date)
// THIS IS WHERE I NEED HELP
}
case .monthly?:
if let date = notificationModel.date {
triggerT = cal.dateComponents([.day,.hour,.minute], from: date)
}
case .yearly?:
triggerT = Calendar.current.dateComponents([.month,.day,.hour,.minute], from: (notificationModel.date)!)
case .oneOff?:
triggerT = Calendar.current.dateComponents([.year,.month,.day,.hour,.minute], from: (notificationModel.date)!)
case .none:
DispatchQueue.main.async {
if let category = self.notificationModel?.category, let title = self.notificationModel?.title {
Toast.down("An error was discovered in \(category). Please change the occurance value for the following \(title)")
}
}
}
} else {
print("NOTIFICATION MODEL IS CORRUPT")
}
return triggerT
}
func add(notification: NotificationModel){
let content = UNMutableNotificationContent()
if let title = notification.title,
let body = notification.body,
let identifier = notification.identifier {
content.title = title
content.body = body
content.sound = UNNotificationSound.default()
content.categoryIdentifier = (notification.category?.rawValue)!
content.setValue("YES", forKeyPath: "shouldAlwaysAlertWhileAppIsForeground")
var trigger : UNCalendarNotificationTrigger?
if let triggerType = self.triggerType {
if let occurance = notification.occurance {
if occurance > 0 {
}
}
trigger = UNCalendarNotificationTrigger(dateMatching: triggerType, repeats: true)
} else {
return
}
let interval = Date().timeIntervalSince1970
let identifierString = "2\(interval)"
var request : UNNotificationRequest!
if notification.reminderType == .alternateDays {
print("ADDING TIMER NOTIFICATION")
print("REMINDER TIME = \(notification.date)")
// 172800 = two days
let newTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 172800,
repeats: true)
request = UNNotificationRequest(identifier: identifierString,
content: content, trigger: newTrigger)
} else {
request = UNNotificationRequest(identifier: identifierString,
content: content, trigger: trigger)
}
center.add(request, withCompletionHandler: { (error) in
if let error = error {
// Something went wrong
print(error.localizedDescription)
} else
{
print("ADDING NOTIDCIATION \(content.title)")
}
})
//SNOOZE OR DELETE NOTIFICATIONS
let snoozeAction = UNNotificationAction(identifier: "Snooze", title: "Snooze", options: [])
let deleteAction = UNNotificationAction(identifier: "UYLDeleteAction",title: "Delete", options: [.destructive])
//Create a category with the actions: This requires another unique identifier (you probably want to define these magic strings in an enum):
let category = UNNotificationCategory(identifier: notification.category!.rawValue,
actions: [snoozeAction,deleteAction],
intentIdentifiers: [], options: [])
//Register the category with the notification center. It is recommended to do this early in the app lifecycle.
center.setNotificationCategories([category])
//To include this action in our notifications we need to set the category in the notification content:
} else {
print("Failed to add notification")
}
}
однако, я хочу через день и не хочу использовать ограничение на 64 уведомления.
спасибо за ваше время
Thomas