Getting the best behavior from phone call requests using ‘tel’ in an iOS app

Almost seven years ago when the iPhone was first released, there was a “Greg’s Head” post about iPhone telephone hyperlinks, remarking on how “tel” was used as part of a URL request to initiate a phone call from a web page in mobile safari.

The use of tel is still the most common way that a native app requests a phone call. This is done via a shared application object:

In this case, the use of tel will immediately call the number without prompting the user. When the user stops the call, Apple’s phone app remains active. In order to return to the app from which they called the number, the user needs to hit the home button and tap on the app icon. This is hardly an ideal experience for the user, and it does not encourage continued use of the app once a phone call is finished.

The pros and cons of telprompt

But, there is an alternative to tel that is much more well-behaved.

Using telprompt instead of tel in the openURL method will not only prompt the user if they wish to call the number, but after the call is finished the user will be directed back to the app instead of the Apple’s phone app.

It is hard to imagine many cases where a native app developer would prefer the use of tel over telprompt, and yet tel is more commonly used.

The primary reason for this is that Apple’s URL Scheme Reference does not mention telprompt, implying that Apple does not support the use of telprompt. While there is some concern that the use of telprompt might lead to a rejected app from the app store, there have been no reports of this occurring. A more substantial concern is that Apple might disallow the use of telprompt in a native app sometime in the future, leading to unexpected behavior in a published app.

 

UIWebview privately uses telprompt when sent a tel request

You can get telprompt behavior in your native app without explicitly referencing by loading a URL using tel in a UIWebView. The web view will privately execute the request using telprompt.

Worst case scenario with this solution: Apple changes the manner in which a UIWebView handles a load request with tel (i.e., having it actually use tel privately instead of telprompt).

We have implemented this in RZUtils as a component called RZTelprompt which uses a couple of class methods and a static UIWebView to make the call:

An example project

In addition to the RZTelprompt component in RZUtils, here’s a github repository with an Xcode 5.1 example project demonstrating RZTelprompt and how it compares to making phone calls via UIApplication.


Do you have a project in mind? We’d love to work with you. If you’d like an opportunity to work on projects with us, check out our Careers page. We’re hiring!

9 thoughts on “Getting the best behavior from phone call requests using ‘tel’ in an iOS app”

  1. > When the user stops the call, Apple’s phone app remains active.

    This part is no longer true. In iOS 8, if I use the UIApplication call to open the URL, ending the call drops me back into the app.

  2. Yeah, as of 8.3 ‘tel’ now performs the same behavior as ‘telprompt’

  3. Is there a way to provide a custom prompt or override the system prompt (the standard alert) in order to edit the title and dialogue copy?

    • You can use a UIAlertController to present whatever alert you want, and then just use [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@”tel:555-555-5555″]. It will do what you want. You can see this in action on the Invaluable live auctions app that we did for iPhone.

      • That’s not true. I downloaded and tried Invaluvable auction app and you have a UITableView cell with the phone number and phone icon. When I tap it, I get the standard Apple prompt to call the number with OK and Cancel buttons.
        That is not the same as a custom UIAlertController that then calls the telprompt. You’re basically just calling the telprompt directly.

        • @Frak sorry if my answer was unclear. We use a UIAlertController that we’ve configured to look like the telprompt alert: telephone number as the title, no message, preferredStyle:UIAlertControllerStyleAlert, Cancel and Call buttons. In the Call action handler, we call -[UIApplication openURL:].

  4. @IBAction func customerCare(sender: AnyObject) {
    let url:NSURL = NSURL(string: “telprompt://994”)!
    UIApplication.sharedApplication().openURL(url)
    }

    this code work well but when i try to send call request
    i mean to dial *804# this
    like this ->

    @IBAction func customerCare(sender: AnyObject) {
    let url:NSURL = NSURL(string: “telprompt:// *804# “)!
    UIApplication.sharedApplication().openURL(url)

    give me un error please can u help me guys ?
    thank you

    • This would probably be better suited for a Stack Overflow post. If you post your question there, and post the link here or message me on Twitter @ZevEisenberg, I’d be happy to take a look.

  5. How can I call to a number while keeping the dialer in the background and the app in the foreground only?

Leave a Comment