Scheduling local notifications to repeat daily from tomorrow - swift

I'm trying to schedule a local notification to fire every day, at a specific time, but from tomorrow.
e.g. "Trigger a notification every day at 2 pm, from tomorrow"
This is how I set up my schedule function.
func scheduleNotifications(date: Date, identfier: String, after: Bool) {
let content = UNMutableNotificationContent()
content.title = "App"
content.body = "Test."
content.sound = .default
content.userInfo = ["Hour": Int(hourFormatter.string(from: date)) ?? 0]
let afterDay = Calendar.current.date(byAdding: .day, value: after ? 1 : 0, to: Date())
var components = Calendar.current.dateComponents([.hour, .minute], from: afterDay!)
components.hour = Int(hourFormatter.string(from: date)) ?? 0
components.minute = Int(minuteFormatter.string(from: date)) ?? 0
let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)
let request = UNNotificationRequest(identifier: identfier, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request)
}

This code is for daily notification just call it in tomorrow schedule time
func setupNotificationSettings() {
DispatchQueue.main.async {
let content: UNMutableNotificationContent = UNMutableNotificationContent()
content.title = AppName
content.body = "APP_Body"
content.sound = UNNotificationSound.default
let trigger: UNTimeIntervalNotificationTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 86400, repeats: true)
let request: UNNotificationRequest = UNNotificationRequest(identifier: "\(AppName)_Local", content: content, trigger: trigger)
let center: UNUserNotificationCenter = UNUserNotificationCenter.current()
center.removeDeliveredNotifications(withIdentifiers: ["\(AppName)"])
center.removeDeliveredNotifications(withIdentifiers: ["\(AppName)"])
center.add(request) { (error) in
}
}
}

Related

Will this code send a notification on this day every month?

I have this code that should send a notification to the user on the same day every month. However I'm can't simulate this, so I can't test it. I was wondering if any of you could proof check it, to ensure it does send a notification every month.
Thanks
static func addNotification(){
let center = UNUserNotificationCenter.current()
let addRequest = {
let content = UNMutableNotificationContent()
content.title = "Test"
content.subtitle = "Test"
content.sound = UNNotificationSound.default
var dateComponents = DateComponents()
dateComponents.day = 31
dateComponents.hour = 12
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
let request = UNNotificationRequest(identifier: "", content: content, trigger: trigger)
center.add(request)
}
center.getNotificationSettings { settings in
if settings.authorizationStatus == .authorized{
addRequest()
}
else{
center.requestAuthorization(options: [.alert, .badge, .sound]) { success, error in
if success{
addRequest()
}
}
}
}
}

How to schedule local notification from iOS14 widget?

I would like to schedule a local notification from iOS14 widget.
How can I do it?
I tried implementing the following:
let center = UNUserNotificationCenter.current()
center.delegate = self
let content = UNMutableNotificationContent()
content.title = "Some Title"
content.body = "Some Body"
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: true)
let request = UNNotificationRequest(identifier: UUID().uuidString,
content: content, trigger: trigger)
center.add(request) { (error) in
if error != nil {
// Handle any errors.
}
I did with this.
func createDate(day: Int, month : Int, hour: Int, minute: Int, year: Int)->Date{
var components = DateComponents()
components.hour = hour
components.minute = minute
components.year = year
components.day = day
components.month = month
components.timeZone = .current
let calendar = Calendar(identifier: .gregorian)
return calendar.date(from: components)!
}
// 📢///CreateNitification
func scheduleNotification(at date: Date, identifierUnic : String, body: String, titles:String) {
let triggerWeekly = Calendar.current.dateComponents([.day, .month, .hour,.minute, .year], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerWeekly, repeats: true)
let content = UNMutableNotificationContent()
content.title = titles
content.body = body
content.sound = UNNotificationSound.default
content.categoryIdentifier = "todoList2"
let request = UNNotificationRequest(identifier: identifierUnic, content: content, trigger: trigger)
// UNUserNotificationCenter.current().delegate = self
/// UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: ["textNotification2"])
/// UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
UNUserNotificationCenter.current().add(request) {(error) in
if let error = error {
print(" We had an error: \(error)")
}}
}
// Call
func callNotifications(){
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
let adte = createDate(day: 3, month: 6, hour: 16, minute: 51, year: 2021)
scheduleNotification(at: adte, identifierUnic: UUID().uuidString, body: "Widgets on Work", titles: "check 123")
}
func getTimeline(in context: Context, completion: #escaping (Timeline<Entry>) -> ()) {
callNotifications()
var entries: [SimpleEntry] = []
// Generate a timeline consisting of five entries an hour apart, starting from the current date.
let currentDate = Date()
for hourOffset in 0 ..< 5 {
let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
let entry = SimpleEntry(date: entryDate)
entries.append(entry)
}
let timeline = Timeline(entries: entries, policy: .atEnd)
completion(timeline)
}
Notification is working fine
but one thing is pending, how can I call UNUserNotificationCenter.current().delegate = self?
Thanks

How do I make multiple local notifications on Swift?

The bottom line is that I made one local notification for a time interval of 10 seconds.
How do I add multiple notifications to this code with different time delays? That is, different notifications with different delays (several hours, days, and so on).
If this is possible, please use the example of my code.
I was told that I need to put a different identifier: "content" and different times. But I don't understand what parts of the code I need to duplicate.
import UIkit
import UserNotifications
class ViewController UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let center = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent()
content.title = "Hi"
content.body = "Bear"
content.sound = UNNotificationSound.default
content.threadIdentifier = "local-notifications"
let date = Date(timeIntervalSinceNow: 10)
let dateComponents = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
let request = UNNotificationRequest(identifier: "content", content: content, trigger: trigger)
center.add(request) {(error) in
if error != nil {
print (error)
}
}
}
```
You can create method scheduleNotification(identifier:content:date:) in UNUserNotificationCenter extension ,
extension UNUserNotificationCenter {
func scheduleNotification(identifier: String, content: UNMutableNotificationContent, date: Date) {
let dateComponents = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
self.add(request) {(error) in
if error != nil {
print (error)
}
}
}
}
Now, call this method for multiple notifications with the appropriate parameters that you want to use, i.e.
Example-1:
let content1 = UNMutableNotificationContent()
content1.title = "Hi"
UNUserNotificationCenter.current().scheduleNotification(identifier: "content1", content: content1, date: Date(timeIntervalSinceNow: 10))
Example-2:
let content2 = UNMutableNotificationContent()
content2.title = "Hello"
UNUserNotificationCenter.current().scheduleNotification(identifier: "content2", content: content2, date: Date(timeIntervalSinceNow: 20))

iOS 10 UserNotification Framework. Calendar Trigger

I am on iOS 10.3.2 Beta 4 and xcode 8.3.2. I am attempting to fire a notification at the same time daily, however the notifications never seem to fire. If I do not use the calendar trigger and use the timeinterval trigger they work as expected.
Here is my code
let content = UNMutableNotificationContent()
content.title = "Daily Notification"
content.subtitle = ""
content.body = NSLocalizedString("Hello I am a notification", comment: "Comment")
content.badge = 1
content.sound = UNNotificationSound.default()
let calendar = Calendar.current
var dateComponents = calendar.dateComponents([.day, .month, .year, .hour], from: Date())
dateComponents.hour = 14
dateComponents.minute = 55
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
NSLog("Setting daily notification - \(dateComponents)")
let request = UNNotificationRequest(identifier: "dailyWarning", content: content, trigger: trigger)
center.add(request, withCompletionHandler: { error in
if error != nil {
NSLog("Error occurred")
} else {
NSLog("Request added successfully: %#", request)
}
})
Try creating your trigger like this:
var dateComponents = DateComponents()
dateComponents.hour = 14
dateComponents.minute = 55
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true) // Setting repeats to true will trigger the notification daily
For more information about why providing just the hour and minutes is sufficient see the explanation above Listing 1 in the documentation found here.

UserNotification in 3 days then repeat every day/hour - iOS 10

UILocalNotification has been depreciated so I would like to update my code to the UserNotification framework:
let alertDays = 3.0
let alertSeconds = alertDays * 24.0 * 60.0 * 60.0
let localNotification:UILocalNotification = UILocalNotification()
localNotification.alertAction = "Reminder"
localNotification.alertTitle = "Reminder Title"
localNotification.alertBody = "Reminder Message"
localNotification.fireDate = Foundation.Date(timeIntervalSinceNow: alertSeconds)
localNotification.repeatInterval = .day
UIApplication.shared().scheduleLocalNotification(localNotification)
How can I set a similar daily or hourly repeat with the UserNotification framework after waiting for the initial notification?
let alertDays = 3.0
let alertSeconds = alertDays * 24.0 * 60.0 * 60.0
let content: UNMutableNotificationContent = UNMutableNotificationContent()
content.title = "Reminder Title"
content.subtitle = "Reminder Subtitle"
content.body = "Reminder Message"
let calendar = Calendar.current
let alarmTime = Foundation.Date(timeIntervalSinceNow: alertSeconds)
let alarmTimeComponents = calendar.components([.day, .hour, .minute], from: alarmTime)
let trigger = UNCalendarNotificationTrigger(dateMatching: alarmTimeComponents, repeats: true)
let request = UNNotificationRequest(identifier: workoutAlarmIdentifier,
content: content,
trigger: trigger)
UNUserNotificationCenter.current().add(request)
{
(error) in // ...
}
It seems like this is not supported, but to make a workaround you could use:
let alertDays = 3.0
let daySeconds = 86400
let alertSeconds = alertDays * daySeconds
let content: UNMutableNotificationContent = UNMutableNotificationContent()
content.title = "Reminder Title"
content.subtitle = "Reminder Subtitle"
content.body = "Reminder Message"
let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: (alertSeconds), repeats: false)
let request = UNNotificationRequest(identifier: workoutAlarmIdentifier,
content: content,
trigger: trigger)
UNUserNotificationCenter.current().add(request)
{
(error) in // ...
}
in combination with didReceive(_:withContentHandler:) you can use:
let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: (daySeconds), repeats: false)
I know this isn't optimal but it should work without using deprecated classes/methods. You use repeats: false since you are intercepting the notification just before the user receives it and creating a new notification. Additionally you can use it in combination with UNNotificationAction and UNNotificationCategory if you handle multiple notifications.
This should work:
func addNotificationForAlarm(alarm: MyAlarm) {
let myAlarmNotifContent = UNMutableNotificationContent()
myAlarmNotifContent.title = "Reminder"
myAlarmNotifContent.body = alarm.activity
myAlarmNotifContent.sound = UNNotificationSound.default()
if alarm.repeatDays.count == 1 {
} else {
for index in 1...alarm.repeatDays.count {
createNotif(date: alarm.date, weekDay: index, content: myAlarmNotifContent)
}
}
}
private func createNotif(date: Date, weekDay: Int, content: UNNotificationContent) {
var dateComponent = DateComponents()
dateComponent.weekday = weekDay
dateComponent.hour = Calendar.current.dateComponents([.hour], from: date).hashValue
dateComponent.minute = Calendar.current.dateComponents([.minute], from: date).hashValue
let myAlarmTrigger = UNCalendarNotificationTrigger(dateMatching: dateComponent, repeats: true)
setupNotificationSettings()
let identifier = "Your-Notification"
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: myAlarmTrigger)
let center = UNUserNotificationCenter.current()
center.add(request, withCompletionHandler: { (error) in
if error != nil {
//TODO: Handle the error
}
})
}