I'm currently developing an iPhone app for a mall.
One of the features is the ability to phone a mall tenant from within the app. I'm using
NSURL *url = [[NSURL alloc] initWithString:#"tel:1(480)555-5555"];
[[UIApplication sharedApplication] openURL:url];
It works as I expect it to, no confirmation dialog and remains in the phone app when the call is completed. I'd rather it return to our app, but whatever...
However, there is another page in the app that is a webview and there are a couple of phone numbers that have been automatically detected. Upon clicking one, the confirmation dialog box opens, and the user is returned to our app.
I'm a little ticked that the behaviour that I want, and was seemingly removed between 3.0 and 3.1, exists in a webview. Ideally, I'd like any phone number to return a user to our app, but I'm okay with neither of them doing it. I just want it to be consistent throughout my app.
Is there a different call I should be using? Can I change the behaviour of phone numbers that have been automatically detected in a webview? (besides disabling it)
Unfortunately, this is not simple to do. The UIWebViewDelegate callback - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType should allow you to intercept these taps but it does not. (Note: in the simulator it does appear to work, but on device it doesn't...) My guess is that the only way to intercept these taps would be at the window level and that would probably be more work than it is worth.
Related
Hey I was wondering if It is possible to add my own application to the UIActionSheet that opens up in safari when you press the share button on the bottom toolbar. I would like to take the user to my application if that button is pressed.
you may want to look at asking the user to add a bookmark in safari to your app.
Tweetie/Instapaper and Summly have similiar features that pass info using javascript to your app from safari bookmarks.
(correction - Tweetie had, not sure if Twitter still use it)
edit - javascript like this works.
javascript:window.location=%27YOUR_CUSTOM_URL_SCHEME://%27+window.location
this takes the current safari url and passes it to your app and you can handle it in
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url;
No. It is not possible to modify core applications like Safari, or any other application for that matter, from your own app (without using private APIs...).
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 launching as an HTML link, the tel URL scheme will be opened if they appear as:
1-408-555-5555
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.
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.
I really want to thank you all you guys first , I began iOS programming learning several weeks ago ,and I have learnt a lot from here these days,.
I have a UIWebView and loading some html content with "loadHTMLString" method, when i click hyperlinks in the UIwebView, It comforms the
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType{
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
[[UIApplication sharedApplication] openURL:[Request URL]];
return NO;
}
return YES;
}
to open a Safari.
My question is: Can I go back from the Safari to the UIWebView? how?
You can't get Safari to send the user back whenever you want, but one way to get back to your application is by creating a custom URL scheme (e.g. myapp://return, or whatever scheme makes sense to you), assuming that the web page the person is going to can have links that are intended to go back to your appliaction.
You can do this by registering that your application handles the URL scheme, and then processing the request appropriately when iOS tells you to. The Apple docs are fairly complete about this.
But if you want your application to be able to arbitrarily pull people back whenever you want, I don't think that's possible. Safari isn't under the control of anyone but Apple.
We have a wifi hotspot that displays a terms of service page before people are allowed to start using it.
After acceptance, a new page with a few links is displayed. I'd like to have those links open in Safari instead of in UIWebView.
I know there's a way to program UIWebView to open links in Safari, but that's not an option as this is the default UIWebView for logging into wifi hotspots and not a custom app.
Is there another way to have the links open in Safari and not in UIWebView? I've tried javascript and I've tried setting the target to _blank.
EDIT: After reading some responses, it seems like the only way to do this is to set the UIWebView delegate. I don't think this is an option because I'm not the one launching the UIWebView.
When the iPhone connects to the network (at least with version 3.0), it checks to see if it's being redirected to a login page. If it is, it does what you're saying with authentication and such inside of a UIWebView. Have you checked to see what it's reporting as the browser in use? If it isn't Mobile Safari, then you could do something server-side the first time someone connects using Mobile Safari.
If it does report as Mobile Safari when it's checking redirection, then another alternative is to figure out what site it tries to go to - maybe apple.com? Then, on the server side, the first time a different URL is loaded, redirect to your links. This will only work when the user opens Mobile Safari, however.
Other than that, I think what you're asking to do is outside of the scope of the current iPhone OS. I'd recommend filing a ‘feature request’ with Apple at bugreport.apple.com.
The only way I know how to do this is to set up a UIWebView delegate and supply something like the following:
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
if (navigationType == UIWebViewNavigationTypeLinkClicked &&
[request.URL isFileURL] == false)
{
[[UIApplication sharedApplication] openURL:request.URL];
return NO;
}
return YES;
}
The code above will cause Safari to open a link clicked on by the user. I know you said you had little control over this UIWebView -- perhaps you have more than you think by setting the delegate?
Use the openURL method of UIApplication:
NSURL *url = [[NSURL alloc] initWithString:#"http://example.com"];
[[UIApplication sharedApplication] openURL:url];
[url release];
An Apple example of this is available as part of the LaunchMe sample.
I have a WebView that loads a simple html page in my resources folder. The page contains links. When the user touches on a link to a Web site, the iPhone will close my app and open Safari. Since the user may not want to leave my app right now, I use:
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
to trap the link touch and show him an alert box, asking him to confirm that he wants to leave my app and go to Safari right now.
Same for an email link, which would close my app and open the user's email program.
However, if I want to similarly trap when the user touches a "tel:402-555-1212" phone call link, it works on the simulator, but on the real device I just get a simple alert box that says "call 4025551212": it clearly is ignoring my custom code for the telephone number link.
Is that a bug? It happens the same way (success on simulator, not on iphone) whether or not I select "detects phone numbers" for the webview in IB. How do I get this to work on the iPhone?
2) And very closely related question: if I click to allow the phone call to happen, when the phone call ends my app returns to its opening page, closing all other views. Is this normal function? There was no memory warning. Did the phone close and then re-open my app? It doesn't do that if click on a link and go to safari: when I close safari my app doesn't open again.
Thanks in advance for any insight.
--Steve
maybe you should set the detectsPhoneNumbers property to NO