9

In UILocalNotification we use NSCalendarUnitMinute like repetition ..... but I can't find in iOS 10 UserNotification doc ... How can I use NSCalendarUnitMinute like repetition in iOS 10 UserNotification?

here is the code which will schedule local notification at 8:30 pm and will repeat after every one minute.

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];
JAL
  • 41,701
  • 23
  • 172
  • 300
S.J
  • 3,063
  • 3
  • 33
  • 66

3 Answers3

3

Although it appears that the old notifications framework had better support regarding this, it's only until, we realise that the new one is better!!

I had similar problems, and below is a sample of how the old notifications can go hand in hand with the new ones.

To be on a safer side, this is 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
            }
        }
    }

Although this isn't exhaustive, I've pretty much covered everything from a minute to a year.

And to be more detailed,

// 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()

As this works for me, it should probably for the rest of you. Please try and let me know if there is an issue.

And, for the exact solution to this question, I'd advise the below.

(Probably, Apple didn't think about such a scenario, but it can be handled)

  1. Schedule a notification for 8:30 PM
  2. When the notification is triggered, remove it and schedule another notification with a different identifier, for the NSCalendarUnitMinute equivalent shown above.
  3. Voila, it works!! (Or did it not?)
Shyam
  • 561
  • 5
  • 22
  • How do you know the notification has been triggered, so to schedule the next? I've seen suggestions of using a notification service extension but they only work for remote notifications :( – CMash Oct 02 '16 at 21:37
  • @CMash. You are right.. Sorry for the wrong info, provided. I was playing around with this, and seem to have it figured out. But, looks like I wasn't able to. :( Still, I'd say the `NSDateComponents`, is pretty clear? If anyone needs to use it. – Shyam Oct 05 '16 at 09:38
1

Use a UNCalendarNotificationTrigger with DateComponents instead of 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)

You set up the date with a DateComponents instance and specify if the notification should repeat with the repeats parameter of the UNCalendarNotificationTrigger initializer.

UNCalendarNotificationTrigger Documentation

Just a heads up that there is a typo in the Apple Docs (as of 6/13). If you use NSDateComponents instead of DateComponents, you will need to explicitly cast your date as DateComponents in the dateMatching parameter.

In response to your comment, I don't believe the behavior you want (changing the frequency of your repeated notification) is supported by UNCalendarNotificationTrigger.

JAL
  • 41,701
  • 23
  • 172
  • 300
  • I want to post UserNotification tomorrow at 8:30 pm that will repeat every minute, How to do that in UserNotification. – S.J Jun 14 '16 at 06:32
  • @S.J I don't see any methods in the API to change the frequency of a notification like you are asking. I only see repeat options once per day. Was that possible with `UILocalNotification`? What you could do is in the handler for the first notification set up a new notification for one minute after the current one fired. I'll keep looking for a way to accomplish the behavior you want. – JAL Jun 14 '16 at 06:35
  • Have you read through the [UserNotifications docs](https://developer.apple.com/reference/usernotifications)? – JAL Jun 14 '16 at 06:36
  • @S.J Yeah, I don't think that is supported. Maybe someone else has a better answer... – JAL Jun 14 '16 at 06:41
  • Is there any way to ask directly to Apple engineer who deliver this presentation. https://developer.apple.com/videos/play/wwdc2016/707/ OR we can also post questions in wwdc. – S.J Jun 14 '16 at 06:45
  • isn't UILocalNotification is better that is capable of doing that and UserNotification is not ......... – S.J Jun 14 '16 at 06:50
  • 1
    @S.J I can try to ask at one of the dev labs at WWDC tomorrow. Can you add the UILocalNotification code that accomplishes this to your question and I will see if I can port it over? – JAL Jun 14 '16 at 07:13
  • hi, any updates regarding the repeat frequency in User Notification. – S.J Jun 23 '16 at 05:02
  • @S.J this behavior is not supported in iOS 10. please consider duping a bug report: http://www.openradar.me/26855019 – junjie Aug 08 '16 at 05:19
  • Any updates on this? I can't see any obvious reasons why minute interval wouldn't be allowed? – DS. Sep 08 '16 at 04:02
  • 1
    @DS. I think this is unsupported by the API. See [UserNotification in 3 days then repeat every day/hour - iOS 10](http://stackoverflow.com/q/38380783/2415822) – JAL Sep 08 '16 at 13:04
  • I'm trying to answer [this question](https://stackoverflow.com/questions/45259189/swift-3-local-notifications-not-firing) but whatever I do the notification doesn't come through. I wrote `let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents as DateComponents, repeats: false)` I tried with `repeating: true`, I also tried without the `as DateComponents` but none worked. I'm not sure if this is a timezone thing. As a tangent question, if you want to set 10:30pm Mon for US, would you just do: `dateComponents.minute = 30; dateComponents.hour = 22 ; dateComponents.day = 2` – mfaani Jul 24 '17 at 21:10
1

Bear with me this is my first post.

We needed the 1 minute repeat interval for our app in ios 10, and used as a workaround a combination the old and new framework.

  1. scheduling the repeating local notifications with the old:

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

This will create and schedule the usual repeating LNs that will show up as UNNotification with a UNLegacyNotificationTrigger

I used a alarmID to connect old and new framework.

Try:

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. responding to actions and fire-ing notifications, manipulating the notification centre:

With the new framework UNUserNotificationCenter methods: willPresentNotification: didReceiveNotificationResponse:

  1. Request authorization and category registration I did for both frameworks in the usual way.

Hope this helps

MauritsK
  • 51
  • 2