How to schedule daily push notifications in swift? - ios

I want my app to notify the user everyday at 13pm. I put this inside my app delegate:
func Notification() {
var Notification = UILocalNotification()
Notification.alertAction = "New Question!"
Notification.alertBody = "Solve the new question!"
Notification.fireDate = NSDate(timeIntervalSinceNow: 0)
UIApplication.sharedApplication().scheduleLocalNotification(Notification)
}
and this inside my application didFinishLaunching:
application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: UIUserNotificationType.Badge | UIUserNotificationType.Sound, categories: nil))
What do I have to do so that my notification is scheduled to fire daily?

just set any past date that at 13pm,
and set repeatInterval as .CalendarUnitDay
let startDate = Date()
var component = Calendar.current.dateComponents([.year, .month, .day, .hour], from: Date())
component.hour = 13
let fireDate = Calendar.current.date(from: component)
notification.repeatInterval = .day;
notification.fireDate = fireDate
Update:
let trigger = UNCalendarNotificationTrigger(dateMatching: component, repeats: true)
var triggerDaily = Calendar.current.dateComponents([.hour,.minute,.second], from: Date())
triggerDaily.hour = 13
triggerDaily.minute = 0
triggerDaily.second = 0
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDaily, repeats: true)
let content = UNMutableNotificationContent()
content.title = "title"
content.body = "body"
content.categoryIdentifier = "todoList"
let request = UNNotificationRequest(identifier: "identifier", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) {(error) in // to do }

Related

How to schedule a local notification two specific days of the week?

I want to schedule a notification to be fired twice a week:
let gregorian = Calendar(identifier: .gregorian)
let now = Date()
[2, 4].forEach { day in
let content = UNMutableNotificationContent()
content.title = "Notif title"
content.body = "Comment"
content.sound = .default
var components = gregorian.dateComponents([.year, .month, .weekdayOrdinal, .day, .hour, .minute, .second], from: now)
components.hour = 11
components.minute = 25
components.second = 0
components.weekdayOrdinal = day
let date = gregorian.date(from: components)!
let triggerDaily = gregorian.dateComponents([.weekdayOrdinal, .hour, .minute, .second], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDaily, repeats: true)
let request = UNNotificationRequest(identifier: "test", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { error in
if let error = error {
print("Oops: \(error)")
} else {
print("Notification created!")
}
}
}
But instead of being fired once on monday and once on wednesday, it gets called two times each day.
What am I doing wrong? Thanks for your help.
because of foreach loop your code schedule two notification with the same identifier. while your code is getting execute the 2nd loop cycle overwrite the request.
I did some R&D and refine your code a bit. On my side, it works perfectly.
Please try the code mention below.
func setNotification() {
let days = [2,4]
func ScheduleNotification(index:Int){
let calendarComponents = NSDateComponents()
calendarComponents.hour = 11
calendarComponents.minute = 25
calendarComponents.second = 0
calendarComponents.weekday = days[index]
let content = UNMutableNotificationContent()
content.title = "Notification title"
content.body = "your message here."
content.sound = UNNotificationSound.default
let trigger = UNCalendarNotificationTrigger(dateMatching: calendarComponents as DateComponents, repeats: true)
let identifier = "UYLLocalNotification\(days[index])"
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: { (error) in
if let error = error {
print(error)
}else{
if index == 0{
ScheduleNotification(index: 1)
}
}
})
}
ScheduleNotification(index: 0)
}
call this function in your viewdidLoad method like.
self.setNotification()
i hope it will save your time.
Simply change the name of identifier of each notification inside the foreach(_:) to something like test2, test4, i.e.
[2, 4].forEach {
let content = UNMutableNotificationContent()
content.title = "title"
content.body = "body"
content.sound = .default
var components = DateComponents()
components.timeZone = TimeZone.current
components.weekday = 11
components.hour = 25
components.minute = 0
components.second = $0
let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)
let request = UNNotificationRequest(identifier: "test\($0)", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { error in
if let error = error {
print("Oops: \(error)")
} else {
print("Notification created!")
}
}
}
You can use .weekday instead of .weekdayOrdinal . According to Apple document
.weekday = A weekday or count of weekdays.
.weekdayOrdinal = weekday ordinal or count of weekday ordinals.
Weekday ordinal units represent the position of the weekday within the
next larger calendar unit, such as the month. For example, 2 is the
weekday ordinal unit for the second Friday of the month.
Try this
let triggerDate = Calendar.current.dateComponents([.weekday,.hour,.minute], from: date as Date)
triggerDat.weekday = day[index]
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDate,
repeats: true)

how to fire local notification on time in swift?

currently I'm working one project in swift 5. I'm trying to push local notifications on specific date & time. I have tried below code and when I set 60.0 interval then its working find but when I set specific date & time then not working.
I have searched & checked so many question but still didn't found the solution. I have checked below questions
get current date from [NSDate date] but set the time to 10:00 am
UNUserNotificationCenter Swift - Local Notification Not Firing in specific cases
let app = UIApplication.shared
let notificationSettings = UIUserNotificationSettings(types: [.alert, .sound], categories: nil)
app.registerUserNotificationSettings(notificationSettings)
let calendar = NSCalendar.current
let date = NSDateComponents()
print("before date get ::=> \(date)")
date.hour = 16
date.minute = 52
date.month = 6
date.day = 20
date.year = 2019
date.timeZone = NSTimeZone.system
print("after custom date get ::=> \(date)")
let alarm = UILocalNotification()
alarm.fireDate = calendar.date(from: date as DateComponents)
alarm.timeZone = NSTimeZone.default
alarm.alertTitle = "Data success"
alarm.alertBody = "successfuly"
alarm.soundName = "Sound.wav"
app.scheduleLocalNotification(alarm)
app.scheduleLocalNotification(alarm)
let content = UNMutableNotificationContent()
content.title = NSString.localizedUserNotificationString(forKey: "Elon said:", arguments: nil)
content.body = NSString.localizedUserNotificationString(forKey: "Hello Tom!Get up, let's play with Jerry!", arguments: nil)
content.sound = UNNotificationSound.default
content.badge = UIApplication.shared.applicationIconBadgeNumber + 1 as NSNumber;
content.categoryIdentifier = "com.elonchan.localNotification"
// Deliver the notification in 60 seconds.
let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 60.0 , repeats: false)
let request = UNNotificationRequest.init(identifier: "FiveSecond", content: content, trigger: trigger)
// Schedule the notification.
let center = UNUserNotificationCenter.current()
center.add(request)
}
I expect to set specific date & time to fire local notification.
You have to use the UNCalendarNotificationTrigger not UNTimeIntervalNotificationTrigger and UILocalNotificaion is deprecated
let mutable = UNMutableNotificationContent()
mutable.body = "message"
mutable.title = "title"
var date = DateComponents()
date.hour = 16
date.minute = 52
date.month = 6
date.day = 20
date.year = 2019
let trigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: false)
let request = UNNotificationRequest(identifier: "key", content: mutable, trigger: trigger)
UNUserNotificationCenter.current().add(request)
This code will help you on how to send a local notification every day. You can set an hour and minute.
func setUpLocalNotification(_ hour: Int, _ minute: Int) {
print("Local Notification Setup")
let calendar = NSCalendar(identifier: .gregorian)!;
var dateFire = Date()
// if today's date is passed, use tomorrow
var fireComponents = calendar.components( [NSCalendar.Unit.day, NSCalendar.Unit.month, NSCalendar.Unit.year, NSCalendar.Unit.hour, NSCalendar.Unit.minute], from:dateFire)
if (fireComponents.hour! > hour
|| (fireComponents.hour == hour && fireComponents.minute! >= minute) ) {
dateFire = dateFire.addingTimeInterval(86400) // Use tomorrow's date
fireComponents = calendar.components( [NSCalendar.Unit.day, NSCalendar.Unit.month, NSCalendar.Unit.year, NSCalendar.Unit.hour, NSCalendar.Unit.minute], from:dateFire);
}
/// -> If you want to get tomorrow date you can use this code.
/*
dateFire = dateFire.tomorrow!
*/
// set up the time
fireComponents.hour = hour
fireComponents.minute = minute
// schedule local notification
dateFire = calendar.date(from: fireComponents)!
let localNotification = UILocalNotification()
localNotification.fireDate = dateFire
localNotification.alertBody = "alert body"
localNotification.alertTitle = "alert title"
localNotification.repeatInterval = NSCalendar.Unit.day
localNotification.soundName = UILocalNotificationDefaultSoundName;
UIApplication.shared.scheduleLocalNotification(localNotification);
}
extension Date {
var tomorrow: Date? {
return Calendar.current.date(byAdding: .day, value: 1, to: self)
}
}

UILocalNotification repeatInterval breaks timeZone and fireDate

I'm scheduling a batch of notifications in my app, some with repeat intervals, others just single fires at a specific date. I'm setting my notifications using this method to create the notifications:
func notification(date: Date, repeatUnit: NSCalendar.Unit?) -> UILocalNotification {
let notification = UILocalNotification()
notification.category = "ReminderCategory"
notification.alertTitle = "Test"
notification.alertBody = "Test Body"
notification.soundName = "Sound1.m4a"
notification.fireDate = date
notification.repeatInterval = repeatUnit ?? NSCalendar.Unit(rawValue: 0)
notification.timeZone = TimeZone.init(secondsFromGMT: 0)!
return notification
}
The notifications fire at the correct times (for the local timezone) if the repeatUnit variable is set to be any of the NSCalendar.Unit units.
However, if I don't set a repeatInterval, the notifications fireDates are somehow set in the past and they fire as soon as I schedule the notifications.
Does anyone have any idea what's going on?
This works for me.
let center = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent()
content.title = "Title"
content.body = "Your text"
content.categoryIdentifier = "reminder-notification"
content.sound = UNNotificationSound.default()
var dateComponents = DateComponents()
dateComponents.hour = Calendar.current.component(.hour, from: date)
dateComponents.minute = Calendar.current.component(.minute, from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
center.add(request)

Swift: Converting Local Notification to User Notification IOS 10

I have recently updated my project to IOS 10, which has caused any local notifications I had registered to not fire. I have tried to convert the local notification to user notifications but it is not having the same effect. Here is the original code I tried to convert. Within viewDidLoad:
guard let settings = UIApplication.shared.currentUserNotificationSettings else { return
}
if settings.types == UIUserNotificationType() {
let ac = UIAlertController(title: "Cant Schedule", message: "No Permission", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
present(ac, animated: true, completion: nil)
return
}
var dateComp: DateComponents = DateComponents()
dateComp.year = 2017;
dateComp.month = 01;
dateComp.day = 28;
dateComp.hour = 11;
dateComp.minute = 0;
(dateComp as NSDateComponents).timeZone = TimeZone.current
let calender:Calendar = Calendar(identifier: Calendar.Identifier.gregorian)
let date:Date = calender.date(from: dateComp)!
let notification = UILocalNotification()
notification.fireDate = date
notification.alertBody = "Notification!"
notification.alertAction = "You just Received a notification!"
notification.soundName = UILocalNotificationDefaultSoundName
notification.userInfo = ["customField1": "w00t"]
notification.repeatInterval = NSCalendar.Unit.weekOfYear
UIApplication.shared.scheduleLocalNotification(notification)
This caused a local notification to fire at 11:00 am every saturday.
Here is the code I used to try and achieve the same effect in IOS 10:
func scheduleNotification(at date: Date) {
let calendar = Calendar(identifier: .gregorian)
let components = calendar.dateComponents(in: .current, from: date)
let newComponents = DateComponents(calendar: calendar, timeZone: .current, month: components.month, day: components.day, hour: components.hour, minute: components.minute)
let trigger = UNCalendarNotificationTrigger(dateMatching: newComponents, repeats: true)
let content = UNMutableNotificationContent()
content.title = "Notification"
content.body = "You just Received a notification!"
content.sound = UNNotificationSound.default()
let request = UNNotificationRequest(identifier: "textNotification", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) {(error) in
if let error = error {
print("Error")
}
}
}
In viewDidLoad:
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) {(accepted, error) in
if !accepted {
print("Error")
}
}
This code works fine if the user selects the date using a datePicker, but I can't figure out how to programmatically set the date of the notification to the same date I had in the local notification (2017-28-01 11:00), and also how to make the notification fire every week at the same time as there is no repeatInterval property.
Could you explain how you could only specify for example Monday at 11:00 am
It's just a matter of leaving out everything that doesn't apply to the repeated value. Thus, in your case you want to specify the date components hour:11 and weekday:2 and nothing else.
To understand how this works, run this in a playground:
let dc = DateComponents(hour:11, weekday:2)
let greg = Calendar(identifier: .gregorian)
let d = greg.nextDate(after: Date(), matching: dc, matchingPolicy:.nextTime)
You will see that d is this coming Monday at 11AM.
That is exactly what UNNotificationTrigger will do to figure out when to send this notification.
Now, if you also set this to be a repeats trigger, you have just specified every Monday at 11AM.

How to set a weekly local notification in swift

I've got a problem with my code.
I want to set a local notification in xcode7, I'm developing a calendar where you can put your university's courses, the thing is that I'm getting the schedule from a json database and I want to notify 15 min before the class starts, but I do not know why my code is not working.
This is an example where I want to repeat the notification every Monday at 13:40.
Can I only set the day and the hour? or should I specify the month and the year too?
var dateComp:NSDateComponents = NSDateComponents()
dateComp.day = 01;
dateComp.hour = 13;
dateComp.minute = 40;
dateComp.timeZone = NSTimeZone.systemTimeZone()
var calender:NSCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
var date:NSDate = calender.dateFromComponents(dateComp)!
let notification = UILocalNotification()
notification.fireDate = date
notification.alertBody = "Swipe to unlock"
notification.alertAction = "You've got a class soon!"
notification.soundName = UILocalNotificationDefaultSoundName
notification.userInfo = ["CustomField1": "w00t"]
notification.repeatInterval = NSCalendarUnit.WeekOfYear
UIApplication.sharedApplication().scheduleLocalNotification(notification)
**Weekly Local notification for swift 4
let content = UNMutableNotificationContent()
content.title = "LocalNotification"
content.subtitle = "notify"
content.body = "I am Text"
content.categoryIdentifier = "alarm"
content.badge = 1
content.sound = UNNotificationSound.default()
// Configure the recurring date.
var dateComponents = DateComponents()
dateComponents.calendar = Calendar.current
dateComponents.weekday = 3
dateComponents.hour = 13
dateComponents.minute = 10
// Create the trigger as a repeating event.
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
// Create the request
let uuidString = UUID().uuidString
let request = UNNotificationRequest(identifier: uuidString,
content: content, trigger: trigger)
// Schedule the request with the system.
let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.add(request) { (error) in
if error != nil {
// Handle any errors.
print("************Error***************")
}
}
}
please check this function
func setLNotification(weekDay:Int , hour:Int, min:Int, second:Int, alertBody:String, type:String, isRepeate:Bool){
let calender = NSCalendar(identifier: NSCalendarIdentifierGregorian)
let dateComp: NSDateComponents?
let components: NSDateComponents = NSDateComponents()
if weekDay > 0{
components.setValue(-50, forComponent: NSCalendarUnit.Year)
let previousDate = NSCalendar.currentCalendar().dateByAddingComponents(components, toDate: NSDate(), options: NSCalendarOptions(rawValue: 0))!
dateComp = calender?.components([.Year,.WeekOfMonth,.Month], fromDate: previousDate)
dateComp?.hour = hour
dateComp?.minute = min
dateComp?.second = second
dateComp?.weekday = weekDay
}else{
components.setValue(hour, forComponent: NSCalendarUnit.Hour)
components.setValue(min, forComponent: NSCalendarUnit.Minute)
components.setValue(second, forComponent: NSCalendarUnit.Second)
let notifiDate = NSCalendar.currentCalendar().dateByAddingComponents(components, toDate: NSDate(), options: NSCalendarOptions(rawValue: 0))!
dateComp = calender?.components([.Year,.Month,.Day,.Hour,.Minute,.Second], fromDate: notifiDate)
}
let notification = UILocalNotification()
if isRepeate == true{
notification.repeatInterval = NSCalendarUnit.WeekOfYear
notification.repeatCalendar = calender
}
notification.fireDate = calender?.dateFromComponents(dateComp!)
notification.alertBody = alertBody
notification.userInfo = ["day":"\(weekDay)","type":"\(type)"]
UIApplication.sharedApplication().scheduleLocalNotification(notification)
}

Resources