Reputation: 6358
I'm trying to reschedule a notification when user tap on wait notification action. When triggerNotification()
gets called the first time Date
is provided by a Date Picker, but when it's called by a response gets the date from a time interval. Inside the didReceiveResponse
method case:waitActionIdentifier:
I set newDate
and pass that to the triggerNotification
parameter. The delayed notification never arrives.
I don't understand if it's a function calling problem or else because newDate
i see is correct by the print of it.
Here's the code:
class ViewController: UIViewController {
@IBAction func datePickerDidSelectNewDate(_ sender: UIDatePicker) {
let selectedDate = sender.date
let delegate = UIApplication.shared.delegate as? AppDelegate
// delegate?.scheduleNotification(at: selectedDate)
delegate?.triggerNotification(at: selectedDate)
}
}
and the AppDelegate
import UIKit
import UserNotifications
@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
UNUserNotificationCenter.current().delegate = self
configureCategory()
triggerNotification(at: Date())
requestAuth()
return true
}
let category = "Notification.Category.Read"
private let readActionIdentifier = "Read"
private let waitActionIdentifier = "Wait"
private func requestAuth() {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (success, error) in
if let error = error {
print("Request Authorization Failed (\(error), \(error.localizedDescription))")
}
}
}
func triggerNotification(at date: Date) {
// Create Notification Content
let notificationContent = UNMutableNotificationContent()
//compone a new Date components because components directly from Date don't work
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)
//create the trigger with above new date components, with no repetitions
let trigger = UNCalendarNotificationTrigger(dateMatching: newComponents, repeats: false)
// Configure Notification Content
notificationContent.title = "Hello"
notificationContent.body = "Kindly read this message."
// Set Category Identifier
notificationContent.categoryIdentifier = category
// Add Trigger
// let notificationTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 10.0, repeats: false)
// // Create Notification Request
let notificationRequest = UNNotificationRequest(identifier: "test_local_notification", content: notificationContent, trigger: trigger)
//
// Add Request to User Notification Center
UNUserNotificationCenter.current().add(notificationRequest) { (error) in
if let error = error {
print("Unable to Add Notification Request (\(error), \(error.localizedDescription))")
}
}
}
private func configureCategory() {
// Define Actions
let read = UNNotificationAction(identifier: readActionIdentifier, title: "Read", options: [])
let wait = UNNotificationAction(identifier: waitActionIdentifier, title : "Wait", options: [])
// Define Category
let readCategory = UNNotificationCategory(identifier: category, actions: [read, wait], intentIdentifiers: [], options: [])
// Register Category
UNUserNotificationCenter.current().setNotificationCategories([readCategory])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
switch response.actionIdentifier
{
case readActionIdentifier:
print("Read tapped")
case waitActionIdentifier:
let actualDate = Date()
let newDate: Date = Date(timeInterval: 10, since: actualDate)
self.triggerNotification(at: newDate)
print("Wait tapped")
print(actualDate)
print(newDate)
default:
print("Other Action")
}
completionHandler()
}
}
Upvotes: 1
Views: 355
Reputation: 6358
After trying different thing with @VIP-DEV and @Honey I finally understood where the problem with rescheduling notification when tapping on the wait action button from the notification.
Inside the func triggerNotification(at date: Date)
scope I was getting the date components without seconds let newComponents = DateComponents(calendar: calendar, timeZone: .current, month: components.month, day: components.day, hour: components.hour, minute: components.minute)
so when the new call of the function was made with a let newDate: Date = Date(timeInterval: 5.0 , since: actualDate)
date, of course those seconds weren't taken into account and the date used was already passed, hence..no rescheduling .
let newComponents = DateComponents(calendar: calendar, timeZone: .current, month: components.month, day: components.day, hour: components.hour, minute: components.minute, second: components.second)
is the final date with components including seconds.
Upvotes: 0