I've searched and searched, but I can't seem to find a fix for this problem.
For some reason, I can not get 'tel:' links to work in a UIWebView. When the links are clicked, the message "The URL can't be shown" appears. Clicking on the same link in Safari works perfectly and dials the number.
This problem started with iOS 5. These links worked perfectly in iOS 4.2 and 4.3.
I'm not sure what other information might be useful, so please let me know if I need to clarify.
Thanks!
EDIT:
Here is the actual code in use...
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSURL *url = request.URL;
if ([url.scheme isEqualToString:@"tel"]) {
return YES;
}
if (![url.scheme isEqualToString:@"http"] && ![url.scheme isEqualToString:@"https"]) {
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
return NO; // Let OS handle this url
}
}
[NSThread detachNewThreadSelector:@selector(startBusy) toTarget:self withObject:nil];
return YES;
}
If I take out the first if statement, the number gets dialed immediately with no confirmation. I'd really like it to function the way it used to by giving an alert, giving you the option to hit either 'Call' or 'Cancel' before dialing the number.
If you created the UIWebView in a .xib, select the UIWebView and check its attributes in the Attribute Inspector. The first heading should be 'Web View', and under that it provides a list of checkboxes marked 'Detection'. Ensure that 'Phone Numbers' is checked.
If launching as an HTML link, the tel URL scheme will be opened if they appear as:
If you are launching from a native URL string (meaning you coded this in Objective-C and are not serving it via a WebView), your URL string should look like this:
Note: This only works with iOS devices that have the Phone app installed (that means iPhone only). iPad & iPod Touch devices will display a warning message.
Note 2: Ensure the phone numbers you are passing do not contain spaces or other special characters (such as * and #).
Code Feedback
Based on your code, things are a bit clearer now. You comment about how nothing happens when you leave the first
if
statement in theshouldStartLoadWithRequest
method (where you returnYES
). This is exactly the behavior you should see because your app is not the Phone app. Only the Phone app can handle thetel:
URL scheme. By returningYES
, you are telling the OS that your app will handle the phone call, but it cannot. You get the call when that conditional is removed because the next block, which checksif ([[UIApplication sharedApplication] canOpenURL:url])
allows thesharedApplication
(which, in this case, is the Phone app) to launch the call.How Things Work & What You Want
The OS is not going to handle showing the Call/Cancel alert dialog for you. That is up to you. It shows up in Safari because the Safari app's
shouldStartLoadWithRequest
method undoubtedly responds to thetel:
scheme by showing aUIAlertView
. Your conditional forif ([url.scheme isEqualToString:@"tel"])
should, whenYES
, trigger aUIAlertView
with a Call and Cancel button. On Call, you will tell thesharedApplication
toopenURL
; on Cancel, you will not issue the call & you will also want to returnNO
so your app does not attempt toloadWithRequest
.Self-Correcting Edit
To be fair about errors in my own thought process, I'm leaving my responses above.
I believe the Call/Cancel dialog is, in fact, a feature of the OS. Apologies for the inaccuracy.
I'd also erroneously glanced over your code's passing off URL handling to sharedApplication only occurring when the scheme was
http
orhttps
.After another look at the code, I wonder if, by any chance you have debug options on in Safari? I believe this prevents the alert from popping up. Also--just to double-check the obvious--you aren't trying this inside the simulator, correct? What happens if you remove the conditional check for
http
/https
and just use thecanOpenURL
check?However, aside from the error in my comments on the conditional & dialog itself, you still should not be returning
YES
. To make a phone call, you should only be able to pull that off by passing it tosharedApplication:openURL
and ensuring you returnNO
because your app is not the Phone app. The only reason you'd want to returnYES
in this method is if your app is going to handle atel:
link in a special way that doesn't involve sending it to the Phone app.