I have been attempting to implement an instance of local notifications without much luck. It seems that it tries to schedule the notification before the closure for the request is completed and therefore never gets scheduled correctly.
I have the two following methods constructed for the request and send:
func requestNotificationAuthorization(myDate: Date) {
let authOptions = UNAuthorizationOptions.init(arrayLiteral: .alert, .badge, .sound)
self.userNotificationCenter.requestAuthorization(options: authOptions) { (success, error) in
if let error = error {
print(error.localizedDescription)
}
}
}
func sendNotification(myDate: Date) {
let content = UNMutableNotificationContent()
content.title = "My Title"
content.body = "Placeholder for data from Firebase"
content.sound = .default
let triggerDaily = Calendar.current.dateComponents([.hour, .minute], from: myDate)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDaily, repeats: true)
let identifier = "LocalNotification"
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
userNotificationCenter.add(request, withCompletionHandler: { (error) in
if let error = error {
print("Error")
}
})
}
The following are the calls for these methods:
let newDate = formatter.date(from: myDate)
self.requestNotificationAuthorization(myDate: newDate!)
self.sendNotification(myDate: newDate!)
I'm not sure how to hold off with the sendNotification call until I'm sure that the requestNotification has been completed successfully. If anyone is willing to provide some useful help with this, I would be most appreciative.
Larme got it right, if someone knows how to give him credit other my saying so here I would appreciate it.
Related
I am scheduling daily repeating notifications by setting only hour, minutes and seconds:
func addNotification(fireDate: Date)
{
let notificationCenter = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent()
content.title = "Some title"
content.body = "Some message"
content.sound = .default
content.categoryIdentifier = "MyCategory"
let calendar = Calendar(identifier: .gregorian)
let triggerDate = calendar.dateComponents([.hour, .minute, .second], from: fireDate)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDate, repeats: true)
let requestID = UUID().uuidString
let notificationRequest = UNNotificationRequest(identifier: requestID, content: content, trigger: trigger)
notificationCenter.add(notificationRequest) { error in
if let error = error
{
print(error.localizedDescription)
}
}
}
Now I would like to be able to cancel all notifications for current day, so I could receive notifications starting with tomorrow. I tried to subclass UNCalendarNotificationTrigger in order to change nextTriggerDate, but there is an error when adding a notification using my custom trigger class. Cannot find a way to achieve this, if I cancel a scheduled notification at certain time, I will not receive that notification anymore. Any ideas are appreciated.
I have this app with a daily notification at 12pm. If the user does something, I want to cancel the notification that day.
Is there a way to cancel the notification that day, but the rest of the days keep working the same?
private func setUpNotification() {
// Ask Permission
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
}
// Create content for notification
let content = UNMutableNotificationContent()
content.title = "I'm a notification!"
content.body = "Don't forget to track your cigarretes!"
// Configure the recurring date.
var dateComponents = DateComponents()
dateComponents.calendar = Calendar.current
dateComponents.hour = 12
dateComponents.minute = 00
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
// Create the request
let uuidString = UUID().uuidString
let request = UNNotificationRequest(identifier: uuidString, content: content, trigger: trigger)
//Register the request
center.add(request) { (error) in
if error != nil {
// Handle any errors.
print(error?.localizedDescription)
}
}
}
I have this code below to test how local notification works every hour. But im not getting anything.
Also, is there a way to send different local notifications messages in different times? and im just calling the LocalNotificationHour() in viewDidLoad()
I just started learning swift, so im sorry in advance.
--
#objc func LocalNotificationHour() {
let user = UNUserNotificationCenter.current()
user.requestAuthorization(options: [.alert,.sound]) { (granted, error) in}
let content = UNMutableNotificationContent()
content.title = "Local Notification"
content.body = "This is a test."
var dateComponents = DateComponents()
dateComponents.calendar = Calendar.current
dateComponents.hour = 1
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
let uuid = UUID().uuidString
let request = UNNotificationRequest(identifier: uuid, content: content, trigger: trigger)
user.add(request) { (error) in print("Error")}
}
var dateComponents = DateComponents()
dateComponents.calendar = Calendar.current
dateComponents.hour = 1
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
This basically takes todays date and sets the time to 1am. Using: UNCalendarNotificationTrigger(dateMatching: you are telling the notification to trigger at 1am today and then repeat at the same time each day.
To trigger a notification based on a time interval you should use the UNTimeIntervalNotificationTrigger.
// Fire in 60 minutes (60 seconds times 60)
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: (60*60), repeats: false)
You can schedule your notification for every minute by adding following code:
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { (success, error) in
if error == nil, !success {
print("Error = \(error!.localizedDescription)")
} else {
let content = UNMutableNotificationContent()
content.title = "Local Notification"
content.body = "This is a test."
content.sound = UNNotificationSound.default
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 60, repeats: true)
let uuid = UUID().uuidString
let request = UNNotificationRequest(identifier: uuid, content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}
}
I have setup a local notification system so that I can fire a notification at a certain time every day. This time is determined by the user and I store it as a string. I will break down all the steps I have done in the code to follow but basically, my problem is that the notification won't fire.
Step 1:
In this step I setup an alert to ask permission to send a notification:
let center = UNUserNotificationCenter.current()
let options: UNAuthorizationOptions = [.alert, .badge, .sound]
center.requestAuthorization(options: options) { (granted, error) in
if granted {
application.registerForRemoteNotifications()
}
}
Step 2:
In this step I setup the function I call to send a notification:
static func sendNotification(stringDate: String) {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
let content = UNMutableNotificationContent()
content.title = "Title"
content.body = "Detail"
content.badge = 1
if let date = dateFormatter.date(from: stringDate) {
let calendar = Calendar.current
let hour = calendar.component(.hour, from: date)
let minute = calendar.component(.minute, from: date)
var dateComponents = DateComponents()
dateComponents.hour = hour
dateComponents.minute = minute
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
let request = UNNotificationRequest(identifier: "dateDone", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}
}
Step 3:
I then call this function in my app delegate file like so:
func applicationDidEnterBackground(_ application: UIApplication) {
let defaults = UserDefaults.standard
if defaults.object(forKey: "currentUser") != nil {
if User.current.desiredTimeForNews.characters.contains("A") {
let stringToBeConverted = User.current.desiredTimeForNews.replacingOccurrences(of: "AM", with: "")
HelperFunctions.sendNotification(stringDate: stringToBeConverted)
} else {
let stringToBeConverted = User.current.desiredTimeForNews.replacingOccurrences(of: "PM", with: "")
HelperFunctions.sendNotification(stringDate: stringToBeConverted)
}
}
}
IMPORTANT: As you can see within my function I take in a "stringDate" parameter. This variable has a string value of my date. I then convert this to a date value. Through using breakpoints and print statements I have seen that all my values including the date, hour, minute, etc are all NOT nil.
Overall, my problem is that the notification is never sent. However I know for a fact that it is called as I have used breakpoints to prove that. Any help would be appreciated!
For me personally, I ran it on a real device and it worked. Although it should work on a simulator it didn't for me. So I would try and run it on a real device before looking at anything else!
The code seems to be ok. Should work on the device and also on the simulator. My guess is that the trigger time just happens at a different time, then what you would expect.
Insert this check below after your setup to see the details:
UNUserNotificationCenter.current()
.getPendingNotificationRequests(completionHandler: { requests in
for (index, request) in requests.enumerated() {
print("notification: \(index) \(request.identifier) \(request.trigger)")
}
})
note 1:Why do you have this line in the code?
application.registerForRemoteNotifications()
note 2:You should check if the requestAuthorization went through ok. With something like this:
UNUserNotificationCenter.current().getNotificationSettings { (settings) in
guard (settings.authorizationStatus == .authorized )
else { print("notifsetup not authorized");return }
guard (settings.soundSetting == .enabled) else {
print("notifsetup sound not enabled");return }
}
I want to repeat local notification every week, before iOS10 there is repeatInterval, but i am not able to find anything suitable to repeat notifications in iOS10.
TimeTrigger and calendarTrigger both have repeat as true or false, where can i apply repeat as weekly, daily, monthly.
Thanks.
Try this.
func scheduleNotification(at date: Date, body: String) {
let triggerWeekly = Calendar.current.dateComponents([.weekday,hour,.minute,.second,], from: date)
let trigger = UNCalendarNotificationTrigger(dateMatching: triggerWeekly, repeats: true)
let content = UNMutableNotificationContent()
content.title = "Dont Forget"
content.body = body
content.sound = UNNotificationSound.default()
//content.categoryIdentifier = "todoList"
let request = UNNotificationRequest(identifier: "textNotification", content: content, trigger: trigger)
UNUserNotificationCenter.current().delegate = self
//UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
UNUserNotificationCenter.current().add(request) {(error) in
if let error = error {
print("Uh oh! We had an error: \(error)")
}
}
}