26

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?

djibouti33
  • 12,102
  • 9
  • 83
  • 116

7 Answers7

9

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.

endowzoner
  • 2,238
  • 3
  • 17
  • 20
  • Yes, the `"This app is not allowed..."` error is telling you to add the scheme to app's .plist file. If the error says `"(null)"`, however, this is an Apple bug (http://www.openradar.me/23022383) and shouldn't be appearing – jimmyjudas Feb 12 '16 at 14:20
8

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"

Polar Bear
  • 918
  • 2
  • 7
  • 19
  • 4
    That is because the simulator doesn't have the `tel` URL scheme. It seems that the error is logged to the console if the URL scheme is not present on the device – jfeldman Sep 24 '15 at 21:46
  • @jfeldman I wan't asking a question about why it doesn't work in the sim. Many things do not work in a Simulator which is why you test on a device. The original poster has still not confirmed if they tested on a device. I was providing the error so that others knew what it looked like. – Polar Bear Sep 26 '15 at 02:16
5

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];
}
Anooj VM
  • 2,593
  • 22
  • 19
  • This works for me and this is right answer. All developers should go with this code.No need to add LSApplicationQueriesSchemes. Thanks, Anooj – Lalit Nov 24 '15 at 12:05
2

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];
}
Steve Forbes
  • 230
  • 1
  • 6
  • Hi, I'm not sure, when to use `URLQueryAllowedCharacterSet` ? There're lots of other character sets available. – Hemang Mar 10 '16 at 07:09
2

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>
Ricardo
  • 2,086
  • 25
  • 35
1

Try running this on a real device instead of simulator. No need to add LSApplicationQueriesSchemes for the tel scheme.

maxkonovalov
  • 3,651
  • 34
  • 36
0

try this one:

NSString *phone_number = [[yourPhoneNumber componentsSeparatedByCharactersInSet:[[NSCharacterSet characterSetWithCharactersInString:@"0123456789-+()"] invertedSet]] componentsJoinedByString:@""];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"telprompt://%@", phone_number]]];
Jabbar
  • 590
  • 1
  • 7
  • 21