Opening tel: links from UIWebView

2019-06-01 19:14发布

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.

2条回答
孤傲高冷的网名
2楼-- · 2019-06-01 19:36

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.

查看更多
Anthone
3楼-- · 2019-06-01 19:46

If launching as an HTML link, the tel URL scheme will be opened if they appear as:

<a href="tel:1-408-555-5555">1-408-555-5555</a>

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:

tel:1-408-555-5555

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 the shouldStartLoadWithRequest method (where you return YES). This is exactly the behavior you should see because your app is not the Phone app. Only the Phone app can handle the tel: URL scheme. By returning YES, 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 checks if ([[UIApplication sharedApplication] canOpenURL:url]) allows the sharedApplication (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 the tel: scheme by showing a UIAlertView. Your conditional for if ([url.scheme isEqualToString:@"tel"]) should, when YES, trigger a UIAlertView with a Call and Cancel button. On Call, you will tell the sharedApplication to openURL; on Cancel, you will not issue the call & you will also want to return NO so your app does not attempt to loadWithRequest.

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 or https.

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 the canOpenURL 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 to sharedApplication:openURL and ensuring you return NO because your app is not the Phone app. The only reason you'd want to return YES in this method is if your app is going to handle a tel: link in a special way that doesn't involve sending it to the Phone app.

查看更多
登录 后发表回答