Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a URL Run when a notification action is pressed?

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"])




    }

}
like image 444
krish Avatar asked Nov 08 '22 04:11

krish


1 Answers

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.

like image 103
Ryan H. Avatar answered Nov 15 '22 06:11

Ryan H.