【问题标题】:How do I set an NSCalendarUnitMinute repeatInterval on iOS 10 UserNotifications?如何在 iOS 10 UserNotifications 上设置 NSCalendarUnitMinute repeatInterval?
【发布时间】:2016-10-14 17:31:12
【问题描述】:

在 UILocalNotification 中,我们使用 NSCalendarUnitMinute 类似重复.....但我在 iOS 10 中找不到 UserNotification doc ... 我如何在 iOS 10 UserNotification 中使用 NSCalendarUnitMinute 类似重复?

这里的代码将安排在晚上 8:30 进行本地通知,并且每隔一分钟重复一次。

UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = pickerDate;
localNotification.alertBody = self.textField.text;
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.repeatInterval = NSCalendarUnitMinute;
localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];

【问题讨论】:

标签: ios objective-c swift ios10 unnotificationrequest


【解决方案1】:

使用UNCalendarNotificationTriggerDateComponents 而不是NSCalendar

var date = DateComponents()
date.hour = 8
date.minute = 30

let trigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)
let content = UNNotificationContent()
// edit your content

let notification = UNNotificationRequest(identifier: "myNotification", content: content, trigger: trigger)

您使用DateComponents 实例设置日期,并使用UNCalendarNotificationTrigger 初始化程序的repeats 参数指定通知是否应重复。

UNCalendarNotificationTrigger Documentation

请注意,Apple Docs 中有一个错字(截至 6 月 13 日)。如果您使用NSDateComponents 而不是DateComponents,则需要在dateMatching 参数中显式转换您的date as DateComponents

针对您的评论,我不相信UNCalendarNotificationTrigger 支持您想要的行为(更改重复通知的频率)。

【讨论】:

  • 我想在明天晚上 8:30 发布 UserNotification,每分钟重复一次,如何在 UserNotification 中做到这一点。
  • @S.J 我在 API 中没有看到任何方法可以像您要​​求的那样更改通知的频率。我每天只看到一次重复选项。 UILocalNotification 有可能吗?您可以做的是在第一个通知的处理程序中在当前通知触发后一分钟设置一个新通知。我会继续寻找一种方法来完成你想要的行为。
  • 你读过UserNotifications docs吗?
  • @S.J 我可以尝试在明天的 WWDC 开发实验室中询问。您能否将完成此操作的 UILocalNotification 代码添加到您的问题中,我会看看是否可以将其移植过来?
  • @DS。我认为 API 不支持这一点。见UserNotification in 3 days then repeat every day/hour - iOS 10
【解决方案2】:

请耐心等待,这是我的第一篇文章。

我们需要在 ios 10 中为我们的应用设置 1 分钟的重复间隔,并将新旧框架组合用作解决方法。

  1. 用旧的安排重复的本地通知:

    UILocalNotification *ln = [[UILocalNotification alloc] init];
    ...
    ln.repeatInterval = kCFCalendarUnitMinute;
    ln.userInfo = @{@"alarmID": ...}
    ...
    [[UIApplication sharedApplication] scheduleLocalNotification:ln];

这将创建和安排通常的重复逻辑节点,这些逻辑节点将显示为带有 UNLegacyNotificationTrigger 的 UNNotification

我使用了一个alarmID来连接新旧框架。

试试:

UNUserNotificationCenter* center = [UNUserNotificationCenter 

currentNotificationCenter];
[center getPendingNotificationRequestsWithCompletionHandler:^(NSArray<UNNotificationRequest *> * _Nonnull requests) {
    NSLog(@"----------------- PendingNotificationRequests %i -------------- ", (int)requests.count);
    for (UNNotificationRequest *req in requests) {
        UNNotificationTrigger *trigger = req.trigger;
        NSLog(@"trigger %@", trigger);
    }
}];
  1. 响应动作和触发通知,操纵通知中心:

使用新框架 UNUserNotificationCenter 方法: willPresent通知: didReceiveNotificationResponse:

  1. 我以通常的方式为这两个框架请求授权和类别注册。

希望对你有帮助

【讨论】:

    【解决方案3】:

    虽然看起来旧的通知框架在这方面有更好的支持,但直到我们意识到新的更好!

    我也遇到过类似的问题,下面是旧通知如何与新通知齐头并进的示例。

    为了更安全,这里是Swift2.3

    // Retrieve interval to be used for repeating the notification
        private func retrieveRepeatInterval(repeatTemp: RepeatInterval) {
            switch repeatTemp {
            case .Never:
                if #available(iOS 10.0, *) {
                    toDateComponents = NSCalendar.currentCalendar().components([.Hour, .Minute, .Day, .Month, .Year], fromDate: timeTemp!)
                    toDateComponents.second = 0
                    repeatNotification = false
                } else {
                    repeatIntervalTemp = nil
                }
            case .EveryMinute:
                if #available(iOS 10.0, *) {
                    toDateComponents.second = 0
                    repeatNotification = true
                } else {
                    repeatIntervalTemp = .Minute
                }
            case .EveryHour:
                if #available(iOS 10.0, *) {
                    toDateComponents = NSCalendar.currentCalendar().components([.Minute], fromDate: timeTemp!)
                    toDateComponents.second = 0
                    repeatNotification = true
                } else {
                    repeatIntervalTemp = .Hour
                }
            case .EveryDay:
                if #available(iOS 10.0, *) {
                    toDateComponents = NSCalendar.currentCalendar().components([.Hour, .Minute], fromDate: timeTemp!)
                    toDateComponents.second = 0
                    repeatNotification = true
                } else {
                    repeatIntervalTemp = .Day
                }
            case .EveryWeek:
                if #available(iOS 10.0, *) {
                    toDateComponents = NSCalendar.currentCalendar().components([.Hour, .Minute, .Weekday], fromDate: timeTemp!)
                    toDateComponents.second = 0
                    repeatNotification = true
                } else {
                    repeatIntervalTemp = .WeekOfYear
                }
            case .EveryMonth:
                if #available(iOS 10.0, *) {
                    toDateComponents = NSCalendar.currentCalendar().components([.Hour, .Minute, .Day], fromDate: timeTemp!)
                    toDateComponents.second = 0
                    repeatNotification = true
                } else {
                    repeatIntervalTemp = .Month
                }
            case .EveryYear:
                if #available(iOS 10.0, *) {
                    toDateComponents = NSCalendar.currentCalendar().components([.Hour, .Minute, .Day, .Month], fromDate: timeTemp!)
                    toDateComponents.second = 0
                    repeatNotification = true
                } else {
                    repeatIntervalTemp = .Year
                }
            }
        }
    

    虽然这并不详尽,但我几乎涵盖了从一分钟到一年的所有内容。

    更详细地说,

    // RepeatInterval
    enum RepeatInterval : String, CustomStringConvertible {
        case Never = "Never"
        case EveryMinute = "Every Minute"
        case EveryHour = "Every Hour"
        case EveryDay = "Every Day"
        case EveryWeek = "Every Week"
        case EveryMonth = "Every Month"
        case EveryYear = "Every Year"
    
        var description : String { return rawValue }
    
        static let allValues = [Never, EveryMinute, EveryHour, EveryDay, EveryWeek, EveryMonth, EveryYear]
    }
    
    var repeatTemp: RepeatInterval?
    
    var repeatIntervalTemp: NSCalendarUnit?
    
    var timeTemp: NSDate?
    
    var toDateComponents = NSDateComponents()
    

    因为这对我有用,所以可能对你们其他人也有用。如果有问题,请尝试让我知道。

    而且,对于这个问题的确切解决方案,我建议如下。

    (可能苹果没有想到这样的场景,但可以处理)

    1. 安排在晚上 8:30 发送通知
    2. 当通知被触发时,将其移除并安排另一个具有不同标识符的通知,对于上面显示的 NSCalendarUnitMinute 等效项。
    3. 瞧,它有效! (或者没有?)

    【讨论】:

    • 你怎么知道通知已经触发,所以安排下一个?我已经看到使用通知服务扩展的建议,但它们仅适用于远程通知:(
    • @CMash。你是对的.. 很抱歉提供了错误的信息。我正在玩这个,似乎已经弄清楚了。但是,看来我是来不及了。 :( 不过,我想说NSDateComponents,很清楚吗?如果有人需要使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-24
    • 2014-01-18
    • 2017-02-13
    • 1970-01-01
    • 2017-02-27
    相关资源
    最近更新 更多