Local Notification every 24 hours in Swift - ios

I'm looking for a way to fire a local notification once every 24 hours from a certain time.
For example:
I have a date picker.
I set the date picker time to 3.02pm.
The next time it's 3.02pm fire a local notification.
Repeat this over and over.
I have managed to successfully call a local notification at a time chosen by a date picker but how do I go about repeating this every 24 hours?

You can repeat a local notification using the repeatInterval property.
To repeat a local notification every day, add this line to your code
myLocalNotification.repeatInterval = NSCalendarUnit.CalendarUnitDay

UILocalNotification is deprecated in iOS 10. Use UNNotificationRequest instead.
myNotificationRequest.trigger = UNTimeIntervalNotificationTrigger(timeInterval: 60*60*24, repeats: false)

In Swift 3
myLocalNotification.repeatInterval = NSCalendar.Unit.day

Related

getPendingNotificationRequests count is not decreasing on notification firing if UNCalendarNotificationTrigger repeat set to true

I am working on a app in that i need to schedule more than 64 notification at a time so i am schedule 64 notifications first and storing rest in database.
All notification is scheduling with UNCalendarNotificationTrigger repeat "true", because that will repeat every day/week.
So problem is that count of pendingNotificationRequest doesn't decrease of notification fires.
if i schedule 60 notifications and 10 notification fires at scheduled time, still i get 60 pending notification request from below code.
if i set to trigger repeat false it works fine, Please assist how can it work in repeat true.
let center1 = UNUserNotificationCenter.current()
center1.getPendingNotificationRequests(completionHandler: { requests in
print("Total Count : \(requests.count)")
})

Check if the current time has just passed 12 o'clock in BACKGROUND

I want to check if the current time (24 hours or 12 hours am/pm) has just passed 12 o'clock.
I did something like that in a view, but in this case I checked if it was not yet 12 in the morning:
let date = Date()
let calendar = Calendar.current
let hora = calendar.component(.hour, from: date)
let minutos = calendar.component(.minute, from: date)
if hora < 12 && minutos <= 59 { ... }
I don't know if I explained it well... I was wondering if I can check if the time has passed in AppDelegate, always in background, and execute a function when 12 am has passed. It is possible?
I don't think you will achieve at least in iOS framework.
Apple won't allow you to execute code at a certain time interval in background. Because it's almost similar what some malwares do.
Additional: But if you don't want to execute code in background rather when in your app's foreground then it's possible using timer.
Depending on what you're trying to do, Local Notifications might be of use to you:
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/SchedulingandHandlingLocalNotifications.html#//apple_ref/doc/uid/TP40008194-CH5-SW1
You can schedule them and they will be delivered to the user even when your app is in the background or not running. The user may then launch your app with a particular action on the notification.

Local Notification Not Firing

I'm trying to use local notification, this is my code:
appdelegate
application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [UIUserNotificationType.Sound, UIUserNotificationType.Alert, UIUserNotificationType.Badge], categories: nil))
notificationViewController
let localNotification:UILocalNotification = UILocalNotification()
var BDate = friend.birthday.componentsSeparatedByString("/")
let date = NSDate.date(year: 2015, month: Int(BDate[1])!, day: Int(BDate[0])! - daysBefore, hour: hour, minute: min, second: 0)
localNotification.soundName = "notificationSound.mp3"
localNotification.alertBody = friend.fullName + " has a birthday today!"
localNotification.fireDate = date
localNotification.timeZone = NSTimeZone.localTimeZone()
localNotification.repeatInterval = NSCalendarUnit.Year
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
friend.birthday is a string - "DD/MM/YYYY"
I'm calling the setNotification function for every friend in a friends array. When there are only one or two friends I get the notification but one there are ~100+ I no longer get the notification.
I know the fireDate is correct, I checked it.
Why the code isn't working?
Each app on a device is limited to 64 scheduled local notifications. The system discards scheduled notifications in excess of this limit, keeping only the 64 notifications that will fire the soonest. Recurring notifications are treated as a single notification.
You can find more detail here
Looks like you're really exceeded the notifications limit. There's several tips and guidelines that might help:
Try to check your date versus NSDate() and schedule notification only if date.timeIntervalSinceReferenceDate > NSDate().timeIntervalSinceReferenceDate (There is a compare method in NSDate, but I prefer to compare raw values)
Scheduling local notifications one-by-one is very expensive for application performance, so you can form an array of notifications and schedule them all at once. Use UIApplication.sharedApplication().scheduledLocalNotifications property for that purpose.
This will allow you effectively reschedule all notifications on every application launch. For example in applicationDidFinishLaunching() delegate method.
And also, this will give you another advantage: you can easily check for notifications limit and, if necessary, add/replace 64-th notification with prompt to user to launch your app to allow it to schedule more notifications. This is a common practice for many applications to deal with Apple's limitations.

iOS Local Notifications Testing

In testing my local notifications, for some reason setting the date and time on my iOS device does not trigger my local notification to appear. My notification's fire date is set to be several days in the future. If I do wait a few days then I will see my local notification.
Why am I not seeing my local notification by setting the date and time on my device?
Below is a sample:
playNotification.FireDate = DateTime.Now.AddHours(71.67f);
playNotification.AlertAction = "Alert text";
playNotification.AlertBody = "Alert body";
playNotification.SoundName = UILocalNotification.DefaultSoundName;
playNotification.ApplicationIconBadgeNumber = badgeCount;
UIApplication.SharedApplication.ScheduleLocalNotification(playNotification);
I should mention that I changed 'AddHours' to 'AddSeconds' and tested this by waiting the specified number of seconds, and the notifications fired as expected. But somehow changing the date and time on my device does not.
You need to set the timeZone of the notifications. By default, the timeZone is set according to your location so it does not affect if you manually change your date and time. To achieve this, you need to set the timeZone to systemTimeZone().
Like this:
notification.timeZone = NSTimeZone.systemTimeZone()
I know this is in swift, but I know very little objective-c.
Hope this helps. :)

Old Local Notifications Firing on iOS

I have a set of UILocalNotifications that I am scheduling. They are firing on time and seem to be working fine. However, on occasion, when a NEW notification fires there are multiple (sometimes only one) OLD notifications that fire along with it.
For example, I schedule a UILocalNotification to take out the trash on Monday at 5pm with no repeat interval. It fires no problem and on time. On Tuesday, I have a UILocalNotification to bring in the trash bins for Tuesday at 5pm, again with no repeat interval. When that one fires, I will see the correct notification for NOW, but also below the current notification will be another notification to take the trash out 1 Day Ago. I have not rescheduled this notification. It appears to be the notification from yesterday.
It is very bizarre and I cannot reproduce it on any sort of consistent basis. I thought that maybe there were some old notifications being added somehow so I added some logic to run through all scheduled notifications and remove any that had a fire date that was in the past but that did not help. Anyone else ever see this problem? Is there some manual clearing of a notification that I need to do when one fires?
EDIT: Added some of the scheduling code
//only schedule if the alert date is later than now
if ([AMDateUtil isNowEarlierThanDate:alertDate]) {
//create the notification and setup some properties
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = alertDate;
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.alertAction = nil;
localNotification.soundName = UILocalNotificationDefaultSoundName;
//add the local notification
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
We had the same issue, but managed to fix it by batching our calls to the API. Instead of calling scheduleLocalNotification each time, instead build an array of all notifications you want to be scheduled. Like this:
NSMutableArray *notifications = [[[UIApplication sharedApplication] scheduledLocalNotifications] mutableCopy];
// add notifications to the mutable array
// same goes for removing notifications
[[[UIApplication sharedApplication] setScheduledLocalNotifications:notifications];
Also make sure you are calling it from the main thread.
Our problems seem to have gone away after doing this.
The first thing that I can think of is to check the repeatInterval of your notifications. It seems that you may want your repeatInterval to be weekly, but the interval seems to be set to daily. To set the repeatInterval to weekly use:
localNotification.repeatInterval = NSWeekCalendarUnit;
Perhaps in some places you may be accidentally using
localNotification.repeatInterval = NSWeekdayCalendarUnit;
which repeats once a day.
If that is not the issue, then perhaps if you post some of your code where you schedule the notifications someone could help you. If a notification has a repeat interval of 0 (or not repeating) then you should not have to manually clear it. If the repeat interval is not 0 then you will have to manually clear it to get it to stop repeating.

Resources