我正在迁移到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.scheduledLocalNotifications
位于定义通知的旧函数中,我认为我已经为其余部分进行了更新。
旧代码:
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(TableViewController)中填充的数组,用于选择行。
现在,当我选择任何一天时,通知都不会触发。
答案 0 :(得分:0)
如果我的理解正确,您希望收到重复的本地通知。 如果是这样,您只需要使用
设置通知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)
瞧瞧
答案 1 :(得分:0)
@Mikael。 @蜜糖。经过一些代码工作后,因为我认为我只能使用.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)
}