canOpenURL failing for system-wide URL schemes

2019-01-23 23:23发布

I'm running iOS 9b5.

In my app, if a device can make a phone call, I want to color the text blue so it looks tappable. If not, I leave it black.

In order to determine the device capabilities, I use:

[[UIApplcation sharedApplication] canOpenURL:@"telprompt://5555555555"]  

As we all know, iOS 9 requires we whitelist any URL schemes we'll be using in our app as a privacy measure.

I have this in my Info.plist:

<key>LSApplicationQueriesSchemes</key>  
<array>  
  <string>telprompt</string>  
</array>  

No matter what I do, I still get canOpenURL: failed for URL: "telprompt://" - error: "(null)". I've tried tel:// and sms:// and I can't seem to avoid that syslog warning.

Does anybody know of a way to detect whether or not a device can make a phone call wtihout triggering these warnings?

7条回答
贪生不怕死
2楼-- · 2019-01-23 23:52

What I discovered so far is, that if the console logs -canOpenURL: failed for URL: "xxx://" - error: "(null)", it actually works. As soon as there is any other error than null, it may not work. If the error is "This app is not allowed to query for scheme xxx", then you have to add this scheme to your app's .plist:

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>xxx</string>
</array>

Strange behavior that the console output looks like an error although there is none, indeed.

查看更多
一纸荒年 Trace。
3楼-- · 2019-01-23 23:54

try this one:

NSString *phone_number = [[yourPhoneNumber componentsSeparatedByCharactersInSet:[[NSCharacterSet characterSetWithCharactersInString:@"0123456789-+()"] invertedSet]] componentsJoinedByString:@""];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"telprompt://%@", phone_number]]];
查看更多
Anthone
4楼-- · 2019-01-24 00:04

In iOS9 I'm using this code and it works:

NSString *assistanceNumber = [[NSUserDefaults standardUserDefaults] objectForKey:@"AssistanceCallMISDN"];
    assistanceNumber= [[assistanceNumber componentsSeparatedByCharactersInSet:[[NSCharacterSet characterSetWithCharactersInString:@"0123456789-+()"] invertedSet]] componentsJoinedByString:@""];
    assistanceNumber = [assistanceNumber stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];


    NSURL *phoneUrl = [NSURL URLWithString:[@"telprompt://" stringByAppendingString:assistanceNumber]];
    NSURL *phoneFallbackUrl = [NSURL URLWithString:[@"tel://" stringByAppendingString:assistanceNumber]];

    if ([UIApplication.sharedApplication canOpenURL:phoneUrl]) {
        [UIApplication.sharedApplication openURL:phoneUrl];
    } else if ([UIApplication.sharedApplication canOpenURL:phoneFallbackUrl]) {
        [UIApplication.sharedApplication openURL:phoneFallbackUrl];
    } else
    {
        [[[UIAlertView alloc] initWithTitle:@"" message:[NSString stringWithFormat:@"No se ha podido realizar la llamada a través de la aplicación. Puede llamar usted al %@", assistanceNumber] delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil] show];
        [_viewEmergency setHidden:YES];
    }

My Info.plist

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>telprompt</string>
    <string>tel</string>
</array>
查看更多
走好不送
5楼-- · 2019-01-24 00:06

As iOS9 deprecates stringByAddingPercentEscapesUsingEncoding, the following can be used to clean the telprompt: URL.

NSString *cleanedString = [[[PHONE NUMBER] componentsSeparatedByCharactersInSet:[[NSCharacterSet characterSetWithCharactersInString:@"0123456789-+()"] invertedSet]] componentsJoinedByString:@""];
//NSString *escapedPhoneNumber = [cleanedString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *escapedPhoneNumber = [cleanedString stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLQueryAllowedCharacterSet]];
NSString *phoneURLString = [NSString stringWithFormat:@"telprompt:%@", escapedPhoneNumber];
NSURL *phoneURL = [NSURL URLWithString:phoneURLString];

if ([[UIApplication sharedApplication] canOpenURL:phoneURL]) {
    [[UIApplication sharedApplication] openURL:phoneURL];
}
查看更多
成全新的幸福
6楼-- · 2019-01-24 00:07

I think you might need to try this on an actual device, or just try it again. I just got this working on my iPhone 5, it looks like you don't even need to add it to the LSApplicationQueriesSchemes. If the app is built with Xcode 7 Beta 6 and you use canOpenURL or openURL like below it seems to work just fine on device.

[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel:555-555-5555"]]

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel:555-555-5555"]]

On the iOS sim I still get the error:
LaunchServices: ERROR: There is no registered handler for URL scheme tel
-canOpenURL: failed for URL: "tel:555-555-5555" - error: "This app is not allowed to query for scheme tel"

查看更多
祖国的老花朵
7楼-- · 2019-01-24 00:08

I got the same error in IOS9 devices. So I have used below code snippet to avoid this error.

NSString *cleanedString = [[[PHONE NUMBER] componentsSeparatedByCharactersInSet:[[NSCharacterSet characterSetWithCharactersInString:@"0123456789-+()"] invertedSet]] componentsJoinedByString:@""];
NSString *escapedPhoneNumber = [cleanedString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *phoneURLString = [NSString stringWithFormat:@"telprompt:%@", escapedPhoneNumber];
NSURL *phoneURL = [NSURL URLWithString:phoneURLString];

if ([[UIApplication sharedApplication] canOpenURL:phoneURL]) {
    [[UIApplication sharedApplication] openURL:phoneURL];
}
查看更多
登录 后发表回答