Local notification: repeat functionality not working as expected - ios

Working on an alarm app and trying to repeat alarm weekly using the below code:
if repeatWeekly {
let triggerWeekly = (Calendar.current as NSCalendar).components([.weekOfYear, .hour, .minute, .second], from: currentDateTime)
trigger = UNCalendarNotificationTrigger(dateMatching: triggerWeekly, repeats: true)
} else {
let triggerDaily = (Calendar.current as NSCalendar).components([.hour,.minute,.second,], from: currentDateTime)
trigger = UNCalendarNotificationTrigger(dateMatching: triggerDaily, repeats: false)
}
In iOS9 using UILocalNotification it is working fine with the following code:
let localNotification = UILocalNotification()
localNotification.repeatInterval = NSCalendar.Unit.weekOfYear
But in iOS10 using UNUserNotification repeat local notification doesn't work properly, it only repeats for 1 week and never shows up for the next week.
For example, if current date time is "1 Sept 2017" then notification will be repeated for "8 Sept 2017" but not repeated for 15 Sept, 22 Sept or so on.
Thanks

Related

Repeating iOS Notification

Is there any way to schedule local notification which fires at specific date and the repeats every minute?
Example: user receive first notification at 8:00 AM and then 8:01, 8:02...
To schedule repeated notification you need date components in trigger initialization.
e.g.
let date = Date(timeIntervalSinceNow: 3600)
let triggerDaily = Calendar.current.dateComponents([.hour,.minute,.second], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDaily, repeats: true)
trigger repeats notification daily
try to setup trigger using only .second in date components
let date = Date(timeIntervalSinceNow: 3600)
let triggerDaily = Calendar.current.dateComponents([.second], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDaily, repeats: true)

Triggering all pending notifications before the time set for it

In the app I'm developing, there is an option for triggering notification x amount of time before the actual time set for the said notification. For example I set the reminder for 10:00. But in the app's local settings, I set the notification to trigger 10 minutes before the time set. So, in this example's case, the notification will trigger in 9:50.
Now, I can do the above when I'm setting time for individual notification. But what I want to do is trigger all pending notifications before the actual time set for it.
This is the function I'm using to set notifications:
func scheduleNotification(at date: Date, identifier: String, threadIdentifier: String, body: String) {
let calendar = Calendar(identifier: .gregorian)
let components = calendar.dateComponents(in: .current, from: date)
let newComponents = DateComponents(calendar: calendar, timeZone: .current, year: components.year, month: components.month, day: components.day, hour: components.hour, minute: components.minute)
let trigger = UNCalendarNotificationTrigger(dateMatching: newComponents, repeats: false)
let content = UNMutableNotificationContent()
content.title = "TestNotification"
content.body = body
content.threadIdentifier = threadIdentifier
content.sound = UNNotificationSound.default()
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) {
error in
if let error = error {
print("Error in delivering notification. Error: \(error.localizedDescription)")
}
}
}
The date is coming from the date set by the date picker. I tried to change trigger properties by using this code:
UNUserNotificationCenter.current().getPendingNotificationRequests { (requests) in
for request in requests {
request.trigger = UNTimeIntervalNotificationTrigger(timeInterval: 10*60, repeats: false)
}
}
But now I get an error saying 'trigger' is a get-only property.
There is no way to change fire time of a scheduled notification , you can remove all of them and re-schedule again

Swift, how to set notifications to first 3 days of every month?

I just want to ask is this even possible?
I've made simple method which as I suspect will fire notification every 1st day of month at 12:00
What I want to do is fires notifications 1st,2nd,3rd day of every month at for ex. 8:00 am and 12:00
func scheduleLocalNotification() {
let calendar = NSCalendar.autoupdatingCurrent
var calendarComponents = DateComponents()
calendarComponents.day = 1
calendarComponents.hour = 12
calendarComponents.minute = 00
let trigger = UNCalendarNotificationTrigger(dateMatching: calendarComponents, repeats: true)
let localNotification = UILocalNotification()
localNotification.alertBody = "Hey, you must go shopping, remember?"
localNotification.soundName = UILocalNotificationDefaultSoundName
}

how to run a function at certain time using swift

In my app, i have implemented functionality to check app version using bundleVersion String. Now, i want to run this function everyday at 8:00 a.m. This is kiosk based app which does not go into background. So, app would be active all the time.
I am using UILocalnotification to schedule a notification for that time. Now, my app has other UILocalnotification as well. I am not sure how can i identify notifications in app delegate didReceiveLocalNotification() method.
My method to schedule notification is below
func scheduleNotification() {
//UIApplication.sharedApplication().cancelAllLocalNotifications()
let notif = UILocalNotification()
let calendar = NSCalendar.currentCalendar()
let date = NSDate()
var calendarComponents = NSDateComponents()
calendarComponents = calendar.components([.Day,.Month,.Year], fromDate: date)
let day = calendarComponents.day
let month = calendarComponents.month
let year = calendarComponents.year
calendarComponents.day = day
calendarComponents.month = month
calendarComponents.year = year
calendarComponents.hour = 8
calendarComponents.second = 0
calendarComponents.minute = 0
calendar.timeZone = NSTimeZone.systemTimeZone()
let dateToFire = calendar.dateFromComponents(calendarComponents)
notif.fireDate = dateToFire
notif.timeZone = NSTimeZone.systemTimeZone()
notif.repeatInterval = NSCalendarUnit.NSWeekdayCalendarUnit
UIApplication.sharedApplication().scheduleLocalNotification(notif)
}
Any idea would be appreciated.
Following method could help you to execute any task at regular interval , i used this method to call webservice at regular interval to provide searching functionality :
let debounceTimer : NSTimer?
func test() {
if let timer = debounceTimer {
timer.invalidate()
}
debounceTimer = NSTimer(timeInterval: 0.3, target: self, selector: Selector("putmethodnamewhichneedstocall"), userInfo: nil, repeats: false)
NSRunLoop.currentRunLoop().addTimer(debounceTimer!, forMode: "NSDefaultRunLoopMode")
}
For specific time daily Refer to this SO link :Repeating local notification daily at a set time with swift
Hope it helps.

How do I use timer or get today's date when suspended iOS app

I'd like to let my app detect date even when iOS app is suspended(neither foreground nor background).
Can app use timer or function which get date in the suspended state?
This question may be simple question, but I couldn't find answer on the web.
Please let me know it is possible or not.
[Edit]
I want to run specified code at tomorrow midnight whenever app is any status.
Thanks in Advance!
This is OS X programming, but maybe you can adapt it.
So setup a timer:
var timer:NSTimer? = NSTimer(timeInterval:30.0, target: self, selector: "timeCheck:", userInfo: nil, repeats: true)
NSRunLoop.currentRunLoop().addTimer(timer!, forMode: NSDefaultRunLoopMode)
NSRunLoop.currentRunLoop().addTimer(timer!, forMode: NSEventTrackingRunLoopMode)
This sets up a timer to fire every 30 seconds. Then what happens when the timer fires:
func timeCheck(timer:UnsafePointer<NSTimer>)
{
let date = NSDate()
let calendar = NSCalendar.currentCalendar()
let components = calendar.components(.CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay , fromDate: date)
let year = components.year
let month = components.month
let day = components.day
// Do something with this
println("Today is \(day), \(month), \(year)")
}
This prints:
Today is 24, 12, 2014
Every 30 seconds.

Resources