【问题标题】:migrating from UILocalNotification to UNUserNotification swift快速从 UILocalNotification 迁移到 UNUserNotification
【发布时间】:2019-02-14 13:46:14
【问题描述】:

我正在迁移到 NUUserNotification,但我遇到了问题,因为我正在使用新框架学习通知,但我不知道旧框架。我希望这不是重复的,因为我阅读了很多关于如何迁移的帖子和教程,但还没有找到让我理解如何应用于此案例的内容。我正在更新的代码不是我的,我花了一些时间来理解它。它是 iOS 警报 (https://github.com/natsu1211/Alarm-ios-swift) 的克隆,我将其合并到我的应用程序中,以便在预定时间/日期等执行操作……我无法理解的两件事是通知重复,据我所知理解现在是针对每个工作日还是单个时间,对吗? fireDate 参数已折旧,那么我将如何重写它? :

private func minFireDateWithIndex(notifications: [UILocalNotification]) -> (Date, Int)? {
    if notifications.isEmpty {
        return nil
    }
    var minIndex = -1
    var minDate: Date = notifications.first!.fireDate!
    for n in notifications {
        let index = n.userInfo!["index"] as! Int
        if(n.fireDate! <= minDate) {
            minDate = n.fireDate!
            minIndex = index
        }
    }
    return (minDate, minIndex)
}

我在更新时遇到问题的另一个代码是检查现有通知,现在 getPendingNotificationRequestsWithCompletionHandler:]if let n = UIApplication.shared.scheduledLocalNotificationsinside 定义了通知的旧函数,我想我已经更新了其余部分。 旧代码:

func setupNotificationSettings() -> UIUserNotificationSettings {

        var snoozeEnabled: Bool = false

        if let n = UIApplication.shared.scheduledLocalNotifications {
            if let result = minFireDateWithIndex(notifications: n) {
                let i = result.1
                snoozeEnabled = alarmModel.alarms[i].snoozeEnabled
            }
        }

        // Specify the notification types.

        let notificationTypes: UIUserNotificationType = [UIUserNotificationType.alert, UIUserNotificationType.sound]
        // Specify the notification actions.
        let stopAction = UIMutableUserNotificationAction()
        stopAction.identifier = Id.stopIdentifier
        stopAction.title = "OK"

        stopAction.activationMode = UIUserNotificationActivationMode.background    // choose activation mode for app on tapping notification

        stopAction.isDestructive = false
        stopAction.isAuthenticationRequired = false

        let snoozeAction = UIMutableUserNotificationAction()
        snoozeAction.identifier = Id.snoozeIdentifier
        snoozeAction.title = "Snooze"
        snoozeAction.activationMode = UIUserNotificationActivationMode.background
        snoozeAction.isDestructive = false
        snoozeAction.isAuthenticationRequired = false

        let actionsArray = snoozeEnabled ? [UIUserNotificationAction](arrayLiteral: snoozeAction, stopAction) : [UIUserNotificationAction](arrayLiteral: stopAction)
        let actionsArrayMinimal = snoozeEnabled ? [UIUserNotificationAction](arrayLiteral: snoozeAction, stopAction) : [UIUserNotificationAction](arrayLiteral: stopAction)
        // Specify the category related to the above actions.
        let alarmCategory = UIMutableUserNotificationCategory()
        alarmCategory.identifier = "myAlarmCategory"
        alarmCategory.setActions(actionsArray, for: .default)
        alarmCategory.setActions(actionsArrayMinimal, for: .minimal)


        let categoriesForSettings = Set(arrayLiteral: alarmCategory)
        // Register the notification settings.
        let newNotificationSettings = UIUserNotificationSettings(types: notificationTypes, categories: categoriesForSettings)
        UIApplication.shared.registerUserNotificationSettings(newNotificationSettings)
        return newNotificationSettings
    }

新代码编辑:

    func setRouteNotification(_ date: Date, onWeekdaysForNotify weekdays:[Int], snoozeEnabled:Bool,  onSnooze: Bool, soundName: String, routeName: String, index: Int) {
    // Notification content
    let routeCheckNotificationContent = UNMutableNotificationContent()
    let datesForNotification = correctDate(date, onWeekdaysForNotify: weekdays)
    routeCheckNotificationContent.title = "Hello!! Are you ready to cycle?"
    routeCheckNotificationContent.body = "Check route for alerts?"
    routeCheckNotificationContent.categoryIdentifier = Id.notificationCategory
    routeCheckNotificationContent.sound = UNNotificationSound.init(named: soundName + ".mp3") // check for the + ".mp3"

    // Define actions
    let check = UNNotificationAction(identifier: Id.checkActionIdentifier, title: " Check", options: [.foreground])
    let wait = UNNotificationAction(identifier: Id.waitActionIdentifier, title: "Wait", options: [])
    // Define category
    let routeCategory = UNNotificationCategory(identifier: Id.notificationCategory, actions: [check, wait], intentIdentifiers: [], options: [])
    // Register category
    UNUserNotificationCenter.current().setNotificationCategories([routeCategory])


    let repeating: Bool = !weekdays.isEmpty
    routeCheckNotificationContent.userInfo = ["snooze" : snoozeEnabled, "index": index, "soundName": soundName, "routeName": routeName, "repeating" : repeating]
    //repeat weekly if repeat weekdays are selected
    //no repeat with snooze notification
    if !weekdays.isEmpty && !onSnooze{
    }

    syncAlarmModel()
    for d in datesForNotification {
        if onSnooze {
            alarmModel.alarms[index].date = Scheduler.correctSecondComponent(date: alarmModel.alarms[index].date)
        }
        else {
            alarmModel.alarms[index].date = d
        }
        // Notification trigger

        let calendar = Calendar(identifier: .gregorian)


        let components = calendar.dateComponents(in: .current, from: d)
        let newComponents = DateComponents(calendar: calendar, timeZone: .current, month: components.month, day: components.day, hour: components.hour, minute: components.minute, second: components.second, weekday: components.weekday)
        let trigger = UNCalendarNotificationTrigger(dateMatching: newComponents, repeats: true)
        // Notification Request
        let routeNotificationRequest = UNNotificationRequest(identifier: "routeNotificationRequest", content: routeCheckNotificationContent, trigger: trigger)

        // Add request
        UNUserNotificationCenter.current().add(routeNotificationRequest) { (Error) in
            if Error != nil {
                print("something went wrong with adding notification")
            }
        }
    }
}

var weekdays: [Int]!是一个填充在 WeekdaysViewController (a TableViewController) 中的数组,用于选择行。

现在,当我选择任何一天时,都不会触发通知。

【问题讨论】:

    标签: ios swift unusernotification


    【解决方案1】:

    @米凯尔。 @蜜糖。在用代码挣扎了一下之后,因为我认为我只能使用 .weekday 组件来设置重复,我发现我可以使用相同的逻辑,即使用 Date 设置每天重复的通知,因为我将选定的日期存储到一个数组中,所以我确实设置了一个 for in 循环来为每个存储的日期设置一个具有唯一标识符的新通知。 最终代码为:

            func setRouteNotification(_ date: Date, onWeekdaysForNotify weekdays:[Int], snoozeEnabled:Bool,  onSnooze: Bool, soundName: String, routeName: String, index: Int) {
                // Notification content
                let routeCheckNotificationContent = UNMutableNotificationContent()
                let datesForNotification = correctDate(date, onWeekdaysForNotify: weekdays)
                routeCheckNotificationContent.title = "Hello!! Are you ready to cycle?"
                routeCheckNotificationContent.body = "Check route for alerts?"
                routeCheckNotificationContent.categoryIdentifier = Id.notificationCategory
                routeCheckNotificationContent.sound = UNNotificationSound.init(named: soundName + ".mp3") // check for the + ".mp3"
    
                // Define actions
                let check = UNNotificationAction(identifier: Id.checkActionIdentifier, title: " Check", options: [.foreground])
                let wait = UNNotificationAction(identifier: Id.waitActionIdentifier, title: "Wait", options: [])
                // Define category
                let routeCategory = UNNotificationCategory(identifier: Id.notificationCategory, actions: [check, wait], intentIdentifiers: [], options: [])
                // Register category
                UNUserNotificationCenter.current().setNotificationCategories([routeCategory])
    
    
                let repeating: Bool = !weekdays.isEmpty
                routeCheckNotificationContent.userInfo = ["snooze" : snoozeEnabled, "index": index, "soundName": soundName, "routeName": routeName, "repeating" : repeating]
                //repeat weekly if repeat weekdays are selected
                //no repeat with snooze notification
                if !weekdays.isEmpty && !onSnooze{
                }
    
                syncAlarmModel()
                var counter = 0
    
                for d in datesForNotification {
                    if onSnooze {
                        alarmModel.alarms[index].date = Scheduler.correctSecondComponent(date: alarmModel.alarms[index].date)
                    }
                    else {
                        alarmModel.alarms[index].date = d
                    }
                    // Notification trigger
    
                    let calendar = Calendar(identifier: .gregorian)
    
    
                    let components = calendar.dateComponents(in: .current, from: d)
                    var newComponents = DateComponents(calendar: calendar, timeZone: .current, month: components.month, day: components.day, hour: components.hour, minute: components.minute, second: components.second, weekday: components.weekday)
                    newComponents.weekday = weekdays[counter]
                    let trigger = UNCalendarNotificationTrigger(dateMatching: newComponents, repeats: true)
                    // Notification Request
    //                let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)
                    let routeNotificationRequest = UNNotificationRequest(identifier: "routeNotificationRequest\(counter)", content: routeCheckNotificationContent, trigger: trigger)
    
                    // Add request
                    UNUserNotificationCenter.current().add(routeNotificationRequest) { (Error) in
                        if Error != nil {
                            print("something went wrong with adding notification")
                        }
                    }
                    print("added request\(counter)")
                    counter = ( counter + 1 )
    
                }
                print(alarmModel.alarms)
            }
    

    【讨论】:

      【解决方案2】:

      如果我理解正确,您希望获得重复的本地通知。 如果是这样,你只需要设置你的通知

      let dateInfo = Calendar.current.dateComponents([.weekday,.hour,.minute], from: aDateWithTheDayHourAndMinuteYouWantToTriggerTheNotification)
      let trigger = UNCalendarNotificationTrigger(dateMatching: dateInfo, repeats: true)
      let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
      

      等等

      【讨论】:

      • 我刚刚将weekday: components.weekday添加到我自己的``newComponents` 中,它应该是它。我确实收到通知和操作。伟大的。我只需要尝试确定在选定的日子重复是否有效。我会做一个测试,今晚我会得到结果。谢谢。
      • 修改后,当我从 WeekdaysViewController 通知中选择任何一天时,都不会触发,有什么想法吗?
      • 我有一个奇怪的行为。通知似乎不会在您将其设置为第二天的那一天触发..很奇怪,对吗?昨天我确实为周五和周六的 00:01 设置了通知.. 它触发了。今天早上我为星期六 7:33 设置了一个..它没有触发..
      • 你能看看我的编辑吗?我有这种奇怪的行为,我真的不明白。为重复添加参数 .weekday 后会自动将重复设置为每天吗?可能是我的工作日数组与此冲突吗?
      • @Ahmet 新浪 Ustem。我看到你在stackoverflow.com/questions/45061324/… 中编辑了一个答案,这似乎是解决我的问题的方法,但我正在努力解决这个问题。你能看出我错在哪里了吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      相关资源
      最近更新 更多