problem using tel: URL to initiate a call - iphone

I'm trying to initiate a call from within an iPhone app.
This related code works and opens Safari as expected:
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"http://www.apple.com"]];
But, when I replace the http URL with a tel URL the resulting code does not invoke the phone app:
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel:3035551212"]];
No exceptions or alerts are generated (in the simulator or on a device).
Any idea what the problem might be with my invocation?
Thanks.

The iphone will dial a number using either of the formats listed below. But, it will do nothing if you are in the simulator. It took me 30 minutes of banging my head to figure this out.
[[UIApplication sharedApplication]
openURL:[NSURL URLWithString:#"tel://15415551234"]];
[[UIApplication sharedApplication]
openURL:[NSURL URLWithString:#"tel:15415551234"]];
[[UIApplication sharedApplication]
openURL:[NSURL URLWithString:#"tel:1-541-555-1234"]];
Link for Apple documentation on the tel: url scheme
Link for openURL documentation

(and )are actually no problem if you use stringByAddingPercentEscapesUsingEncoding as suggested by samiq. Same goes for +, / and spaces. It's a URL, so escaping seems natural.
If I'm guessing right, Apple's regular phone number recognition will be used in the tel: scheme handler, if you escape correctly.
(missing reputation to make it a comment)

As #bentford said one might get miscarried because the simulator does show an alert when you try to click on a phone on the contacts app, this is just an alert that gets generated because the app checks whether or not the tel: protocol is supported on the device or not.
Adding to what he writes you might want to also add support to escape any special characters or spaces as in:
NSString *phoneStr = [NSString stringWithFormat:#"tel:%#",[self.contactDetails objectForKey:#"phone"]];
NSString *escaped = [phoneStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:escaped]];
Hope it helps.
Cheers.

If your phone number has ( or ) in it, the Phone app will not launch.

Haven't had any problems with it using tel:{phone-number} and invoking it the same way you are. Only works on the iPhone device, though.
One thing I did have to do was strip out extraneous characters (like all parentheses, spaces, dashes and dots) out of the phone string. Some of the examples above (but not the original post) have dashes. That might be the problem.

I found that the issue was due to characters that where not allowed for tel:// URI - the following code solved my problem:
NSMutableCharacterSet *charSet = [NSMutableCharacterSet new];
[charSet formUnionWithCharacterSet:[NSCharacterSet whitespaceCharacterSet]];
[charSet formUnionWithCharacterSet:[NSCharacterSet punctuationCharacterSet]];
[charSet formUnionWithCharacterSet:[NSCharacterSet symbolCharacterSet]];
NSArray *arrayWithNumbers = [str componentsSeparatedByCharactersInSet:charSet];
NSString *numberStr = [arrayWithNumbers componentsJoinedByString:#""];

I just ran into this when trying to add a "Call" button to a UIAlertView. I had the following code to handle the call:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex != 0)
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel:1-602-555-1212"]];
}
}
It wouldn't open anything, just like you. I even tried a regular http URL. It turned out I had forgotten to set the delegate to self. That's probably your problem also.

some additional info about making phone calls via url scheme (as I think someone may find it useful)
How to use tel: with * (star, asterisk) or # (hash, pound) on iOs?

Here is an update on how to derive a phone number in 2018 (where iOS 11 and 12 are most common):
NSString *phoneNumberURLString = [#"tel://" stringByAppendingString:[result.phoneNumber
stringByAddingPercentEncodingWithAllowedCharacters:
[NSCharacterSet URLPathAllowedCharacterSet]]];
NSURL *phoneNumberURL = [NSURL URLWithString:phoneNumberURLString];
samiq's answer was what I used initially until I found that my app would crash due to a nil NSURL being created (and later being passed into a collection object) due to failing to properly escape a phone number formatted like so: (###) ###-####. The aforementioned code resolves this.

I got the same problem and at last I found the reason was that there was a space in the phone number (for better formatting). After removing the space it worked fine.

The URL should be tel://3035551212 and not tel:3035551212...
Add that // and it should work.

Related

Cordova 3.1 open link in Safari on iOS6

I'm building a iOS app with Cordova 3.1. I have a link I would like to open in Safari. I've installed the org.apache.cordova.inappbrowser plugin and it worked well on my iPhone (iOS 7) and on the simulator (iOS5;iOS6.1;iOS7) but if I try (iOS6) on all devices it doesn't work.
Does anybody know how to fix this or tried it on a real device running iOS6?
I'm using this code to open the link:
window.open('http://www.google.nl', '_system');
well I've implemented this through native side (Objective C)
Add this method in 'MainViewController.m'
- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL *url = [request URL];
NSString *str = url.absoluteString;
NSRange range = [str rangeOfString:#"http://"];
NSRange range1 = [str rangeOfString:#"https://"];
if (range.location != NSNotFound || range1.location != NSNotFound) {
[[UIApplication sharedApplication] openURL:url];
return NO;
}
else {
return [ super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType ];
}
}
This take cares of both 'http' and 'https' link for both iOS6 & iOS7, and opens the link in default browser of the device.
I know this is an old question, but I've encountered it too and just written a small plugin to help with it. Siddhartha's answer is almost right, but when I used it, it intercepted all web requests, including those to my index.html, and this seemed to move my app into Safari. What I needed was a way to handle only explicit requests, so I could open specific (external) URLs in Safari.
There are many similar questions about Phonegap, which appears to embed special handling for window.open with _system. That would be nice, but Cordova doesn't have this functionality.
In the end, I wrote a small plugin that embeds enough Objective C (closely modelled on Siddhartha's answer) but due to the magic of plugins, it can be executed on demand, using cordova.exec. I'd love this to patch into window.open to achieve the same functionality as Phonegap, but that'll be for another day, and it doesn't really affect this answer.
As far as I can tell, in modernish Cordova, this is the only viable strategy.

iOS 7 alternative to CTCall?

In our enterprise iOS app we used
CTCallRef CTCallDial(CFStringRef number);
to do calls from the app (and be able to hide the caller-id
It does not seem to work in iOS 7. Has the API changed there?
(I'm fully aware that this is a private API call and that it can change anytime, but I'm still hoping to find an alternative. Sadly I'm not savvy enough to know how to find all private API that is available)
I think it requires you to sign your app with com.apple.coretelephony.Calls.allow entitlement. I found it in SpringBoard binary. Apple added a whole bunch of new entitlements. So we should expect that many APIs will not work without them. Just for CoreTelephony alone there is four entitlements in SpringBoard.
I asked the same question here in stackoverflow 2 hours after your post...
A first look at the class dump (https://github.com/EthanArbuckle/IOS-7-Headers/blob/master/Frameworks/CoreTelephony.framework/CTCall.h) shows, that this function is missing...
Actually I've tried the same as vualoaithu and got no luck. But I've also tried to use other methods of TUCallCenter object and looks like it works fine. For example following method works:
TUCallCenter *callCenter = [TUCallCenter sharedInstance];
if(callCenter) {
NSLog(#"callCenter is created!");
//Working part
if([callCenter inCall]){
NSLog(#"IN CALL"); // when you press answer button and can talk
}else{
NSLog(#"NOT IN CALL"); // other cases
}
}
Also I've tried following:
TUPhoneNumber* phoneNumber =
[TUPhoneNumber phoneNumberWithDigits:#"55555555"
countryCode:#"1"];
if(phoneNumber) {
NSLog(#"Phone Number obj = %#",phoneNumber);
NSLog(#"Phone Number = %#",phoneNumber.digits);
NSLog(#"Country Code = %#",phoneNumber.countryCode);
}
[callCenter dial:phoneNumber service:0];
But I got exception:
[TUPhoneNumber length]: unrecognized selector sent to instance 0x14dcefd0
Looks Like we are on the way. If someone will find solution. Please post it here.
Thanks.
you can use
[[UIApplication sharedApplication] openURL: [NSURL URLWithString:[NSString stringWithFormat:#"tel:%#",num]]];
But you can't close call screen when call finished

Dialing a phone number in Xcode [duplicate]

This question already has answers here:
Make a phone call programmatically
(13 answers)
Closed 8 years ago.
Hello I want the user to click on a button and the button will open the actual iPhone phone app.
Any ideas or tutorials on how to do this?
You can easily place a call with this line below:
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel:12125551212"]];
You can not open just Phone application to manually enter number. As suggested before you can place a call from your application which will open the default phone calling screen and once you are done with that call it will redirect back to your application.
Just to add (without just copying & pasting the same answer yet again !) that if your phone number contains any spaces, then this line of code will silently fail.
So even if the Phone app says that it's dialling +41 44 123 4567, if you attempt to use the following line in your code, nothing will happen. It won't recognise this as a phone number.
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel:+41 44 123 4567"]];
So, you need to strip out any spaces, then get the Phone app to dial the number, at which point it'll add it's own spaces back into the phone number when it displays it !!
Here's the code I've used (where the phone number is currently displayed in a UILabel called lblPhone):
NSString* phoneNumber = [self.lblPhone.text stringByReplacingOccurrencesOfString:#" " withString:#""];
NSString* actionStr = [NSString stringWithFormat:#"telprompt:%#", phoneNumber];
UIDevice *device = [UIDevice currentDevice];
if ([[device model] isEqualToString:#"iPhone"] ) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:actionStr]];
}
This code also checks whether you're running the app on an iPad. If you are, then we don't want to attempt to dial the number.
Also, as the answer on this thread suggests, you'll see that I've used telprompt: rather than tel: It has two advantages:
First, it makes a small dialog appear, to check that the user really wants to call that phone number:
And secondly, when the user finishes calling this number (and hangs up), it'll return you back into your app. Strangely, using tel: doesn't do this.
(Tested with XCode 5 & iOS 7.1)
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel:<You button title as phone number>"]];

UIApplication OpenUrl double-escaping my URLs

Basically, i'm trying to program a "tweet this" button from inside my application. Depending on their spot in the application, they can click the tweet button and it'll shoot them out to Safari with a tweet message that changes depending on where they are.
In order to create URLs, I have to escape the query string that I want to put in the NSUrl object. So, I do this:
NSString* escapedTweet = [#"Some String With Spaces" stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
After concatenating the base, my url comes out "http://www.twitter.com/home/?status=Some&20String%20With%20Spaces" - looked at it in the debugger and this is definitely the value (as expected). Now, I create my URL and launch safari:
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:escapedUrlString]];
But here's where the issue comes up: OpenUrl appears to be escaping my percent signs, so the actual URL that Safari goes to is "http://www.twitter.com/home/?status=Some%2520String%2520With%2520Spaces", which is obviously a problem since twitter creates the status message as "Some%20String%20With%20Spaces".
NSUrl will NOT allow me to create a URL with spaces in it, so i'm completely lost as to how to get my URLs to just include a %20. Has anyone else run into this issue or found a workaround?
I'm running on an iPad with an up to date OS, not sure if it's the same issue on the iPhone.
Edit: In a nutshell, how do I get openUrl to open http://www.twitter.com/home/?status=Some%20Url%20With%20Spaces without escaping my percent signs and creating a URL like http://www.twitter.com/home/?status=Some%2520Url%2520With%2520Spaces?
I am assuming that escapedUrlString is declared as NSURL *escapedUrlString = [NSURL URLWithString:escapedTweet];. Then your problem probably lies in openURL:[NSURL URLWithString:escapedUrlString]];, because you’re taking an URL, passing it into another URL and then opening it. Fix by passing in escapedURLString (which should be named ‘escapedURL’) instead of URLWithString:….

Using tel: url to initiate a call doesn't return control

I have an app that worked just fine in version 2.2.1 of the iphone, but have ran into an issue when I upgraded my dev iphone to 3.1.2. Before, dialing a number worked fine, as when the call was ended, my application was loaded. Now, after I hit end call, it loads the default phone application. Does anybody know why this is? I've looked at the diff's from sdk 2.x to 3.x and can't find any reason why this would change. Thanks
This was indeed changed from 3.0 to 3.1. If you need the "prompt-for-call" and "relaunch-app-after-call" there are 2 work-arounds:
Option 1: Create a UIWebView and load your tel: URL.
// assuming you have an ivar to store a weak reference to a UIWebView:
// UIWebView *phoneCallWebView;
- (void) dialPhoneNumber:(NSString *)aPhoneNumber
{
NSURL *phoneURL = [NSURL URLWithString:[NSString stringWithFormat:#"tel:%#",aPhoneNumber]];
if ( !phoneCallWebView ) {
phoneCallWebView = [[UIWebView alloc] initWithFrame:CGRectZero];
}
[phoneCallWebView loadRequest:[NSURLRequest requestWithURL:phoneURL]];
}
- (void) dealloc
{
// cleanup
[phoneCallWebView release], phoneCallWebView = nil;
[super dealloc];
}
Option 2: Initiate your call with with the telprompt:<number> URL scheme instead of tel:<number>. Note that this is an undocumented API feature, but it's what UIWebView uses when you tap on a phone number link in a webview (or in MobileSafari). If you are targeting iPhone >= 3.0, there are not any problems using telprompt: (tel: and telprompt: are identical on 3.0). I'm not sure about iPhone OS 2.x.
In general, option 2 works and is easier, but option 1 is actually a "legal" workaround. Unfortunately, there does not seem to be a way to separate the "prompt-for-call" and "relaunch-after-call" behaviors. On iPhoneOS >= 3.1, you can either get both, or neither.
Yes, Apple changed this behavior from 3.0 to 3.1 (I believe, could also be from 2.x to 3.0). They have acknowledged that the change was deliberate and not a bug. There is no workaround that I know of. You just have to live with it a file an enhancement request if you think the old behavior should be made available again.
But both UIWebView and telepump will introduce a "pop up box" require user to confirm if user would like to dial the number. I am wondering if there are some solutions that could get rid of "pop up box" Thank you.
NSURL* url = [[NSURL alloc] initWithString:[NSString stringWithFormat:#"telprompt:%#",[SLUser sharedInstance].ivrNumber]];
[[UIApplication sharedApplication] openURL:url];