I'm working on a project where I need to set a different title for local notification in a specific day (lets say for Monday) with the same trigger time as the days before. How can I proceed with doing it ? I tried creating two different requests one with a repeating parameter and the other not, but then i got a duplicated notification for the "Monday" one.
Any solution to change the title for this case just only for one day and repeating ?
You have to create different UNNotificationRequest with UNCalendarNotificationTrigger and UNMutableNotificationContent to implement this.Then you will get notification with different titles in a week.
For example, create day1 like this:
UNCalendarNotificationTrigger trigger1 = UNCalendarNotificationTrigger.CreateTrigger(new NSDateComponents() { Weekday = 1, Hour = 8}, true);
UNMutableNotificationContent content1 = new UNMutableNotificationContent() { Title = "Day1", Body = "Day1", CategoryIdentifier = "Day1" };
UNNotificationRequest request1 = UNNotificationRequest.FromIdentifier("d1", content1, trigger1);
Related
I have an app where the user needs to complete a task every day. If the user does not complete a task, he/she gets a reminder at 8am the next day with a phrase prompting to complete the task.
We would like to send a phrase every morning but we don't want it to be the same phrase every day.
This is what we have right now:
static func scheduleDailyUnwatchedNotification() {
let notificationMessages = ["Phrase one", "Phrase two", "Phrase 3", "Phrase 4", "Phrase 5"]
let totalMessages = notificationMessages.count
let randomIndex = Int.random(in: 0..<totalMessages)
let center = UNUserNotificationCenter.current()
center.removePendingNotificationRequests(withIdentifiers: ["dailyReminder"])
let content = UNMutableNotificationContent()
content.title = "Reminder"
content.body = notificationMessages[randomIndex]
content.sound = .default
var dateComponents = DateComponents()
dateComponents.hour = 8
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
let request = UNNotificationRequest(identifier: "dailyReminder", content: content, trigger: trigger)
center.add(request)
}
The problem is that even though a random phrase is selected, the notification will always repeat with that same random phrase.
How can we have it repeat with a different phrase?
You’ll need to schedule each different phrased notification manually. However if you’re sending a phrase every day and you have say 50 of them you could schedule each to repeat every 50 days. Then whenever the user opens the app you can always swap around the days the notifications are sent - so the phrases ordering isn’t always the same. It’s not the most ideal but does allow recurring notifications with different titles.
Alternatively if you want to be able to change the notification titles without new app releases/have more control you can use push notifications. This way you can set up a backend to send messages but it does have more overhead from a server perspective.
in my app I send a daily notification to remind the user to visit the app.
This notification is locally delivered every day at 1pm.
func scheduleNotifications() -> Void {
for notification in notifications {
let content = UNMutableNotificationContent()
content.title = notification.title
let todaysDate = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd"
let currentDay = dateFormatter.string(from: todaysDate)
let currentDayInt = Int(currentDay) ?? 0
var datComp = DateComponents()
datComp.hour = 13
datComp.minute = 00
datComp.day = currentDayInt + 1
let trigger = UNCalendarNotificationTrigger(dateMatching: datComp, repeats: true)
let request = UNNotificationRequest(identifier: notification.id, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { error in
guard error == nil else { return }
print("Scheduling notification with id: \(notification.id) on Day \(datComp.day ?? 00) at \(datComp.hour ?? 00) - \(datComp.minute ?? 00)")
}
}
}
As you can see, I added the "current day + 1" lines because if the user opens the app before 1pm, there is no need to deliver the notification on this day.
So every time the user opens the app, I use UNUserNotificationCenter.current().removeAllPendingNotificationRequests() to remove and reschedule the notification for the next day (by recalling the function above).
My issue:
The notification should repeat every day, which it does, as long as the user opens the app.
But if the user does not open the app on one day, there will be no notification on the following days.
Is there a way to mute notifications for the current day so that I don't have to use this "current day + 1"-thing? Or does anyone have a better idea?
Thank you guys.
I think you misunderstood how repeating notifications and your datComp works here.
For example (let's use today's date: May 27)
datComp.hour = 13
datComp.minute = 00
datComp.day = currentDayInt + 1 // in our example it's 28
let trigger = UNCalendarNotificationTrigger(dateMatching: datComp, repeats: true)
means that your notification will get triggered every month on 28th, all parameters your trigger knows is hour, minute, day and by repeating it, will be triggered on every 28th at 13:00.
So the way your app works now is that you set up monthly notification starting from tomorrow, when you open the app you remove that monthly notification and reschedule it for day later. By opening every day it gives you impression that its daily notification but it's not, it's monthly. That's why if you don't open the app nothing shows up next the day, it will show up next month.
You can check my similar explanation here: (top answer there, maybe it is better worded and easier to understand)
Removing scheduled local notification
and my solution for similar problem i had here:
How to set up daily local notification for tasks but don't show it when user completes the task before
I want to make an app just like iOS Reminders app. My problem is the custom repeat part. We can set custom repeats like "Every 2 Months on the third Monday"(the screenshot below) but I don't know how to implement this sort of repeats with User Notification.
What should I have do?
Although the question might be abroad to be fully answered, I would post an answer that should scratch the surface of how you could achieve it by using user notifications.
If you are aiming to let the displaying of the notification is based on a specific date/interval -as you mentioned "Every 2 Months on the third Monday"-, then you should work with UNCalendarNotificationTrigger:
The date and time at which to deliver a local notification.
Example:
import UserNotifications
// first, you declare the content of the notification:
let content = UNMutableNotificationContent()
content.title = "Notification Title"
content.subtitle = "Notification Subtitle"
content.body = "Notification Body"
// now, you should declare the UNCalendarNotificationTrigger instance,
// but before that, you'd need to describe what's the date matching for firing it:
// for instance, this means it should get fired every Monday, at 10:30:
var date = DateComponents()
date.weekday = 2
date.hour = 10
date.minute = 30
// declaring the trigger
let calendarTrigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)
// creating a request and add it to the notification center
let request = UNNotificationRequest(identifier: "notification-identifier", content: content, trigger: calendarTrigger)
UNUserNotificationCenter.current().add(request)
I have an app using local notifications there is a total of 64 notifications, which is the limit of local notifications. I need to repeat each notification every week. I know that to set the repeat interval you use:
alarm.repeatInterval = NSCalendarUnit
I have tried using the .WeekOfYear and .WeekOfMonth. Do they repeat the notification every year or month? And I do not know the calendar unit for weekly. Which one can I use to repeat weekly?
Edit:
This is the code I am using to set the notifications.
let notifyAlarm = UILocalNotification()
let component = NSDateComponents()
component.hour = NSUserDefaults.standardUserDefaults().integerForKey("Hour1")
component.minute = NSUserDefaults.standardUserDefaults().integerForKey("Minute1")
component.weekday = 1
notifyAlarm.fireDate = calendar.dateFromComponents(component)
notifyAlarm.timeZone = NSTimeZone.defaultTimeZone()
notifyAlarm.alertBody = NSUserDefaults.standardUserDefaults().stringForKey("Message1")
notifyAlarm.repeatInterval = NSCalendarUnit.WeekdayOrdinal
notifyAlarm.soundName = NSUserDefaults.standardUserDefaults().stringForKey("Sound1")
app.scheduleLocalNotification(notifyAlarm)
I am setting 64 notifications like that at once. But with different dates.
If you want the notification to fire for first time after a week you need to change the fire date.
I use TimeIntervalSinceNow for this, which is in seconds, so 1 week would be around 604000 seconds.
You can use _ to separate numbers for legibility.
alarm.fireDate = NSDate(timeIntervalSinceNow: 604_000)
Maybe a bit clunky but I think its the easiest for those type of notifications. I do something like this to make it easier.
struct NotificationFireDate {
static let nextDay: NSTimeInterval = 85_000
static let nextWeek: NSTimeInterval = 604_000
}
and than use it like so
alarm.fireDate = NSDate(timeIntervalSinceNow: NotificationFireDate.nextWeek)
Repeat interval should be weekOfYear
alarm.repeatInterval = NSCalendarUnit.WeekOfYear
The first repeating notification should fire 1 week after the first (fireDate) notification fired.
For a full list have a look at this (thanks madmik3)
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSCalendar_Class/#//apple_ref/c/tdef/NSCalendarUnit
How can I handle date change event in swift?
I want to create a set of notification when the date changes.
var localNotification: UILocalNotification = UILocalNotification()
localNotification.alertAction = "Testing notifications on iOS8"
localNotification.alertBody = " Woww it works!!"
localNotification.fireDate = date
UIApplication.sharedApplication().scheduleLocalNotification(localNotification)
You can subscribe to UIApplicationSignificantTimeChangeNotification. This one should fire when the day changes.
Unfortunately this one also fires on other occasions. So you should store a static variable with the date the last time this notification fired and then check if it actually changed the day.
I don't know what you're gonna use it for, but in most cases the general significant time change is what one is looking for.
You could do localNotification.fireDate = NSDate(timeIntervalSinceNow: 1) which will give you a notification 1 day from the current date. This could be further customized to your liking depending on how specific you want the timing to be.
EDIT: As was pointed out in the comments, the timeIntervalSinceNow is calculated in seconds, so 1 would be one second, not one day.
EDIT 2: Trying to answer the question that was asked. If you want to create a notification at midnight every day...
First, create an NSCalendar object
var calendar = NSCalendar()
var calendarComponents = NSDateComponents()
calendarComponents.setDay(29)
calendarComponents.setMonth(6)
calendarComponents.setYear(2015)
calendarComponents.setHour(12)
calendarComponents.setSeconds(0)
calendarcomponents.setMinutes(0)
calendar.setTimeZone(NSTimeZone.defaultTimeZone)
var dateToFire = calendar.dateFromComponents(calendarComponents)
Now we can schedule the notification daily.
localNotification.fireDate = dateToFire
localNotification.setTimeZone(NSTimeZone.defaultTimeZone)
localNotification.setRepeatInterval(kcfCalendarUnitDay)
Syntax might not be perfect, I was translating from Obj-C, but you should get the general idea.
Try adding observer for NSNotification.Name.NSCalendarDayChanged
The down side of this that it triggers only when app is in foreground