I created a notification with two actions. One of my actions is called "Cancel", while the other is called "Call". How do I make the "Call" action run a URL that is in a comment that I added to my code. Here is my code:
func notificationFires(){
/**
URL Code:
if let url = URL(string: "tel://") {
UIApplication.shared.open(url, options: [:])
}
**/
let call = UNNotificationAction(identifier:"call", title:"Call", options:[.foreground])
let cancel = UNNotificationAction(identifier: "cancel", title: "Cancel", options: [.destructive ])
let category = UNNotificationCategory(identifier: "category", actions: [call, cancel], intentIdentifiers: [], options: [])
UNUserNotificationCenter.current().setNotificationCategories([category])
let notification = UILocalNotification()
notification.category = "category"
// 2
notification.soundName = UILocalNotificationDefaultSoundName
notification.fireDate = datePicker.date
// 3
if textField.text == "" {
notification.alertBody = "You have a call right now!"
}
else{
notification.alertBody = self.textField.text
}
// 4
notification.timeZone = NSTimeZone.default
// 5
// 6
notification.applicationIconBadgeNumber = 1
// 7
func application(application: UIApplication!, handleActionWithIdentifier identifier:String!, forLocalNotification notification:UILocalNotification!, completionHandler: (() -> Void)!){
if (identifier == "call"){
if let url = URL(string: "tel://2162964785") {
UIApplication.shared.open(url, options: [:])
}
}else if (identifier == "cancel"){
}
}
UIApplication.shared.scheduleLocalNotification(notification)
func application(application: UIApplication, didReceiveLocalNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
print("Recieved: notification")
let center = UNUserNotificationCenter.current()
center.removeDeliveredNotifications(withIdentifiers: ["notification"])
}
}
Assuming your notification is working correctly, you can conform to UNUserNotificationCenterDelegate
to handle the "call" action.
Something like:
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
if response.actionIdentifier == "call" {
let body = response.notification.request.content.body
if let url = URL(string: "tel://\(body)") {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
}
The body
constant would be set to the phone number that you want to "open".
Also, its important to note that this has to be tested on an actual device. Opening a tel
scheme does nothing in the simulator.
UNUserNotificationCenterDelegate API Reference: https://developer.apple.com/reference/usernotifications/unusernotificationcenterdelegate
EDIT:
You do not call the delegate method. Instead you implement it. The delegate method is called by the UNUserNotificationCenter
.
To get this working, its important to ensure that you set the UNUserNotificationCenter.current()
delegate property to a class that will conform to the UNUserNotificationCenterDelegate
protocol.
For example, if you are handling your notification in your AppDelegate
, you may have something like the following method:
func callNotification() {
let center = UNUserNotificationCenter.center()
// TODO: - Create your actions, category, content, trigger and request...
center.delegate = self // Important!
center.removeAllPendingNotificationRequests()
center.add(request, withCompletionHandler: nil)
}
The method above would be responsible for defining your notification and scheduling it. For brevity, I have left out all of the code that would define the notification since you indicated that this is working. Instead you should note that the delegate
property is being set to self
.
Then in an extension, you would make the AppDelegate
conform to the UNUserNotificationCenterDelegate
and implement the required methods.
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
if response.actionIdentifier == "call" {
let body = response.notification.request.content.body
if let url = URL(string: "tel://\(body)") {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
}
}
Now because your AppDelegate
conforms to the UNUserNotificationCenterDelegate
protocol and you set self
(AppDelegate
) as the UNUserNotificationCenter
's delegate, your implementation of the userNotification(_:didReceive:withCompletionHandler:)
method will be called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With