【问题标题】:How to set a local notification to fire on the last day of each month using UNNotificationRequest?如何使用 UNNotificationRequest 将本地通知设置为在每个月的最后一天触发?
【发布时间】:2021-12-17 12:04:09
【问题描述】:

我试图将本地通知设置为在每个月的最后一天触发,无论是 28 日、29 日、30 日还是 31 日。

使用之前的框架UILocalNotification,我可以指定fireDaterepeatInterval,它可以工作。但是现在我将框架更新为UNNotofication,我尝试使用UNCalendarNotificationTrigger 并将DateComponents' 日期设置为0。然而并没有火。有什么我做错了吗?谢谢!

代码如下。 nextTriggerDate 为零。

var components = DateComponents()
components.hour = 8
components.minute = 0
components.day = 0

let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)
print(trigger.nextTriggerDate())

【问题讨论】:

  • 您的结果是nil,因为您将day 设置为0
  • @shim,你是对的,但是它之前使用 UILocalNotification 工作,将日期设置为 0 它会给我上个月的最后一天。 Calendar.current.date(from: components) 实际上给你 12 月 31 日。问题是这样 dateComponents 不能与 UNCalendarNotificationTrigger 一起使用
  • 请出示您的原始代码进行比较

标签: ios swift unnotificationrequest unnotificationtrigger


【解决方案1】:

您可以使用以下代码,显示通知后计算下一个最后一天的月份。

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge])
    { (granted, error) in
        // Enable or disable features based on authorization
    }
    let current = UNUserNotificationCenter.current()
    current.delegate = self
    setNotificationRequest()
}


func setNotificationRequest(offset: Int = 0) {
    let content = UNMutableNotificationContent()
    content.title = "Alarm"
    content.body = "Alarm for End of Month"
    content.sound = UNNotificationSound.default
    
    var dateCompo = DateComponents()
    dateCompo.day = lastDay(offset: offset)
    let trigger = UNCalendarNotificationTrigger.init(dateMatching: dateCompo, repeats: true)
    let request = UNNotificationRequest(identifier: "alarm-id", content: content, trigger: trigger)
    UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
    UNUserNotificationCenter.current().add(request)
}
func lastDay(offset: Int) -> Int {
    let cal = Calendar.current
    let m = cal.component(.month, from: Date()) + 1
    let y = cal.component(.year, from: Date())
    var comps = DateComponents(calendar: cal, year: y, month: m)
    comps.setValue(m + 1, for: .month)
    comps.setValue(0, for: .day)
    let date = cal.date(from: comps)!
    return cal.component(.day, from: date)
} }


extension ViewController: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    // offset is set to 1 as we want to get last of next month now.
    setNotificationRequest(offset: 1)
    completionHandler([.badge, .sound])
} }

我已经测试过了,对我来说工作正常。

【讨论】:

  • 谢谢。但是看起来这个解决方案依赖于用户打开应用程序来安排下一轮?这并不理想......
  • 下一个通知请求在 userNotificationCenter 回调中设置,这意味着当用户显示通知应用程序时,会自动设置下一个通知请求,因此用户不必打开应用程序。
  • 如文档中所说:userNotificationCenter(_:willPresent:withCompletionHandler:) Asks the delegate how to handle a notification that arrived while the app was running in the foreground. 如果通知中心显示通知,应用在后台,则不会调用。我正在考虑通过安排每年 12 次通知而不是每月通知来解决此问题...
猜你喜欢
  • 2013-05-11
  • 1970-01-01
  • 1970-01-01
  • 2020-01-11
  • 1970-01-01
  • 2022-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多