【问题标题】:Is it possible to have two DateCompontents for one Local Notification?一个本地通知是否可以有两个 DateCompontents?
【发布时间】:2021-03-21 05:10:06
【问题描述】:

我正在尝试为本地通知设置两个不同的时间 - 默认一个是每天上午 10 点(如果用户没有触摸日期选择器来选择他们自己的通知时间,也就是零),一个基于用户的输入。用户输入一个确实有效并每天发送通知,但如果没有选择时间,则默认时间不起作用。

这是我的代码,谁能告诉我我做错了什么?我基本上想检查用户输入是否为零,它应该恢复到默认时间设置。

在设置中:

IBOutlet var userDatePicker: UIDatePicker!

IBAction func pickerValueChanged(_ sender: UIDatePicker) {
    var selectedTime = Date()
    selectedTime = sender.date

    // convert to data type DateComponents
    let convertedSelectedTime = calendar.dateComponents([.hour, .minute,], from: selectedTime)
    let delegate = UIApplication.shared.delegate as? AppDelegate
    delegate?.sendNotification(with: convertedSelectedTime)
    UserDefaults.standard.set(selectedTime, forKey: "SavedTime")
}

在 AppDelegate 中:

func sendNotification(with userSelectedTime: DateComponents?) {
    let center = UNUserNotificationCenter.current()
    let content = UNMutableNotificationContent()
    content.title = "Testing"
    content.body = "testing"
    var defaultTime = DateComponents()
    defaultTime.hour = 10
    defaultTime.minute = 00`// trying to set default time to 10 am if user never picks a time`
    let components = userSelectedTime ?? defaultTime//option between the two
    let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)
    let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
    center.add(request)
}

【问题讨论】:

    标签: swift uilocalnotification nsdatecomponents


    【解决方案1】:

    试试这个。它的所有字段都是可选的。所以你可以使用你需要的。

    DateComponents(calendar:timeZone:era:year:month:day:hour:minute:second:nanosecond:weekday:weekdayOrdinal:quarter:weekOfMonth:weekOfYear:yearForWeekOfYear:)
    

    let triggerDaily = DateComponents(calendar: Calendar.current,
      timeZone: Calendar.current.timeZone,
      hour: 10, // Use 22 if PM 
      minute: 00,
      second: 00,
      nanosecond: 00)
    
    let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDaily, repeats: false)
    

    更多信息

    DateComponents - Apple


    更新

    在pickerValueChanged 中,每次DatePicker 值更改时,您都会安排通知。那很不好。在那里你应该只存储日期。

    func pickerValueChanged(_ sender: UIDatePicker) {
        UserDefaults.standard.set(sender.date, forKey: "SavedTime")
    }
    

    sendNotification 应该只发送通知。

    func sendNotification(with dateComponents: DateComponents) {
        let center = UNUserNotificationCenter.current()
        let content = UNMutableNotificationContent()
        content.title = "Testing"
        content.body = "testing"
        let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
        let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
        center.add(request)
    }
    

    UIApplication 具有 alife 方法,当应用程序进入后台时会调用该方法。您可以在那里安排通知。

    func applicationDidEnterBackground(_ application: UIApplication) {
        let date = UserDefaults.standard.value(forKey: "SavedTime") as? Date
        if let date = date {
            let convertedSelectedTime = Calendar.current.dateComponents([.hour, .minute,], from: date)
            sendNotification(with: convertedSelectedTime)
        } else {
            let dateComponent = DateComponents(calendar: Calendar.current,
              timeZone: Calendar.current.timeZone,
              hour: 10, // Use 22 if PM
              minute: 00,
              second: 00,
              nanosecond: 00)
           sendNotification(with: dateComponent)
        }
    }
    

    如果UserDefaaults 中存在SavedTime,则使用它。否则使用10:00。


    如果您使用 SceneDelegate,请使用 sceneDidEnterBackground 而不是 applicationDidEnterBackground

    func sceneDidEnterBackground(_ scene: UIScene) {
    
    }
    

    它们都是生命周期方法。

    更多信息。

    Managing Your App's Life Cycle

    UIApplication

    【讨论】:

    • 感谢您的电子邮件!但是,我在哪里可以提供同时采用 userSelectedTime 的选项?如果用户没有选择任何东西,默认时间(上午 10 点)应该是一个后备选项
    • @Tine 你在哪里使用过userDatePicker?你没有保存按钮吗?
    • 它在设置视图控制器中(上面提到过)。然后将其作为参数传递给 AppDelegate 中的 sendNotification 函数。我认为使用 nil 合并可选:let components = userSelectedTime ?? defaultTime 希望如果 userSelectedTime 尚不存在,它将选择 defaultTime 。这显然是有缺陷的,但我不知道该怎么做
    • 哇,谢谢!出于某种原因,它不适用于 AppDelegate,但它适用于 SceneDelegate。非常感谢
    猜你喜欢
    • 1970-01-01
    • 2015-03-09
    • 1970-01-01
    • 1970-01-01
    • 2021-11-05
    • 1970-01-01
    • 1970-01-01
    • 2017-12-30
    • 2012-02-26
    相关资源
    最近更新 更多