I want to make phone call using UIWebView. I tried below code which works fine in if I simply put a button and on button click execute below code. But currently on button click, I call an api and on response I execute below code.
// Make a call to given phone number
- (void)callPhoneNumber:(NSString *)phoneNumber
{
if (!self.webView)
{
webView = [[UIWebView alloc] init];
[self.view addSubview:self.webView];
self.webView.delegate = self;
}
// Remove non-digits from phone number
phoneNumber = [[phoneNumber componentsSeparatedByCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]] componentsJoinedByString:#""];
// Make a call
NSURL * url = [NSURL URLWithString:[NSString stringWithFormat:#"tel:%#", phoneNumber]];
[self.webView loadRequest:[NSURLRequest requestWithURL:url]];
}
Its not even calling webview delegate methods.
What can be the reason?
Please note that I want to call using webview only, so please don't suggest to use native contact app. Using webview keeps flow within the app. When call is ended users is in app only. Using native app, if user wants to come back to my app user has to manually open the app.
To dial a phone number you have to call -[UIApplication openURL:]:
NSString *phoneNumber = #"+5512345678";
NSURL *phoneNumberURL = [NSURL URLWithString:[NSString stringWithFormat:#"tel://%#", phoneNumber]];
[[UIApplication sharedApplication] openURL:phoneNumberURL];
Why not use this?
NSString *phoneNumberURL = [#"telprompt://" stringByAppendingString: phoneNumber];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:phoneNumberURL]];
This takes the user back to the app automatically once the call is finished. I hope that is what you want to achieve using webview.
https://stackoverflow.com/a/12065542/569497
Are you sure self.webView has been initialized?
Change: webView = [[UIWebView alloc] init];
To: self.webView = [[UIWebView alloc] init];
and this: [NSString stringWithFormat:#"tel:phoneNumber"] don't work; try: [NSString stringWithFormat:#"tel:%#",phoneNumber]
Personally, however, I never tried to make a phone call in this way.
If you want to call via UIWebView then use this example:
+ (void)callWithString:(NSString *)phoneString
{
[self callWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"tel:%#",phoneString]]];
}
+ (void)callWithURL:(NSURL *)url
{
static UIWebView *webView = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
webView = [UIWebView new];
});
[webView loadRequest:[NSURLRequest requestWithURL:url]];
}
Related
Im working on a web based application, it contains only one webView, the code below:
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
if ((navigationType == UIWebViewNavigationTypeLinkClicked )) {
[[UIApplication sharedApplication] openURL:[request URL]] ;
}
HUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUD];
// Set determinate mode
[HUD show:YES];
//CAPTURE USER LINK-CLICK.
NSURL *url = [request URL];
NSString *urls= [url absoluteString];
NSString *code = [urls substringFromIndex: [urls length] - 1];
if ( [urls containsString:#".html"] && ![code isEqualToString:#"#"] ) {
_webView.hidden= YES;
}
this code will open all the web views on safari , but i only need to open specific URLs on safari
for example :
http://xxxx/residential/ this must be opened on safari, while all the other pages should be opened on webView inside the application.
Any help
First thing is that you want to open specific urls that should open in Safari instead of UIWebView. But there is not any conditions that fulfill your requirement.
First check your [request url] with your desired url. If both matched then open that url in SFSafariViewController instead of openUrl function. in else conditon you can load your [request url] which you don't want to open in Safari.
Please take a look at this piece of code:
NSString *text = [NSString stringWithFormat:#"%#",
[#"Hello world!" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSString *post = [NSString stringWithFormat:#"fb://publish/profile/me?text=%#", text];
NSURL* url = [NSURL URLWithString:post];
if ([[UIApplication sharedApplication] canOpenURL:url])
{
[[UIApplication sharedApplication] openURL:url];
}
By means of this code I would like to open Facebook app installed on the device and open it on a share dialog with the text string used as a predefined text to share. But unfortunately what it does is just open my timeline. What am I doing wrong? Or is it even possible? I can't find any documentation or tutorial on how to do that properly. Thanks
There is simple way using FacebookSDK's framework. This takes only 2 minutes to go.
FBSDKCoreKit.framework
FBSDKShareKit.framework
If in your device facebook app is not installed then this will open default web browser.
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKShareKit/FBSDKShareKit.h>
// in viewdidload or somewhere else
FBSDKShareLinkContent *content = [[FBSDKShareLinkContent alloc] init];
content.contentTitle = #"Scare Prank";
content.contentDescription = #"Someone just got Scare Pranked with ♫";
content.contentURL = [NSURL URLWithString:soundUrl];
content.imageURL = [NSURL URLWithString:#“some icon url”];
FBSDKShareButton *button = [[FBSDKShareButton alloc] initWithFrame:CGRectMake(0, 0, 200, 43)];
button.center = self.center;
button.shareContent = content;
[self addSubview:button];
So I have a tabbed iOS app, and two of the view controllers in the app each have webViews in them. Nothing else. When these views are opened, they then call the NSURLRequest I have coded in the viewDidLoad method (as we all know). Very typical, basic, simple code.
What I am trying to do but haven't been able to figure out, is how to have these requests called and completed upon app launch, as opposed to being triggered when the view controller is viewed for the first time. It just takes too long to load.
I'm not very experienced with threads and blocks so any advice would help! I do know that all the UI stuff needs to be called on the main thread/queue. I have made an attempt at using another thread (commented out in view controller 2), so any further explanation as to what I already have would be great as well.
VC 1
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *url = [NSURL URLWithString:#"https://soundcloud.com/vanguardsf"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[_music loadRequest:request];
}
VC 2
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect screen = [[UIScreen mainScreen]applicationFrame];
_webView = [[UIWebView alloc]initWithFrame:screen];
_webView.delegate = self;
[self.view addSubview:_webView];
NSString *netGym = #"http://www.netgym.com/login.asp";
NSURL *url = [NSURL URLWithString:netGym];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[_webView loadRequest:request];
NSLog(#"%#", request );
// if (!requestQueue) {
// requestQueue = dispatch_queue_create("come.requestNetgym.load", NULL);
// }
// dispatch_queue_t requestQueue = dispatch_queue_create("come.requestNetgym.load", NULL);
// dispatch_async(requestQueue, ^{
// NSString *netGym = #"http://www.netgym.com/login.asp";
// NSURL *url = [NSURL URLWithString:netGym];
// NSURLRequest *request = [NSURLRequest requestWithURL:url];
// [_webView loadRequest:request];
// NSLog(#"%#", request );
// });
}
You don't have to use GDC to send asynchrounus NSURLRequests - they are asynchronous if You don't use them synchronously on purpose.
You can start the requests in this method:
https://developer.apple.com/library/ios/documentation/uikit/reference/uiapplicationdelegate_protocol/Reference/Reference.html#//apple_ref/occ/intfm/UIApplicationDelegate/application:willFinishLaunchingWithOptions:
This is first place in application when You can execute a code just after launching is finished. You will save some time (little I suppose - this looks like a simple app).
I think that better solution is to cache the downloaded website data. In this case You will download the data first time You enter the app and the second time You will display downloaded content. In the background You will check if website has changed. If so You update the content.
I'm loading a remote webpage into an iOS webview which relies on js and css assets. To improve the performance particularly on 3G networks, I'm hoping to call these assets from files local to the iOS device.
The website backing the iOS app is also used by mobile phone browsers, not just the iOS app, so subclassing NSURLRequest to register my own URL prefix (myurl://) is not ideal.
I already have code that launches mobileSafari for URLs outside of my domain:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSURL *url = [request URL];
NSString *hostname = [url host];
if (![hostname hasSuffix:#".mysite.com"] && navigationType == UIWebViewNavigationTypeLinkClicked) {
[[UIApplication sharedApplication] openURL:url];
return NO;
}
return YES;
}
This method is called from the same controller implementation with code like this:
- (void)viewDidLoad {
[super viewDidLoad];
// ...
webView.delegate = self;
// ...
NSURL *url = [[NSURL alloc] initWithString:([path length] > 0 ? path : #"http://mysite.com/mobile/index")];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
[webView loadRequest:request];
// ...
}
I've reviewed several other questions ( How to use an iPhone webView with an external HTML that references local images? , Dynamically loading javascript files in UIWebView with local cache not working, iOS WebView remote html with local image files, Using local resources in an iPhone webview ) but they all seem to miss a key element to my problem.
The first link has the start of something promising:
if ([url isEqualToString:#"http://path-to-cdn.com/jquery-1.8.2.min.js"]) {
fileToLoad = [[NSBundle mainBundle] pathForResource:#"jquery-1.8.2.min" ofType:#"js"];
}
If that's a sensible approach, I'm stuck on how to get from passing that fileToLoad NSBundle into the webView's loadRequest, since that's expecting a URL.
I think I'm on the right path after realizing that I could use the output of stringByAppendingPathComponent as a URL, like so...
if (![hostname hasSuffix:#".mysite.com"] && navigationType == UIWebViewNavigationTypeLinkClicked) {
NSString *urlString = [url absoluteString];
if ([urlString isEqualToString:#"http://path-to-cdn.com/jquery-1.8.2.min.js"]) {
NSString *tempurl = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"js/jquery-1.8.2.min.js"];
[webView loadRequest:[NSMutableURLRequest requestWithURL:tempurl]];
} else {
[[UIApplication sharedApplication] openURL:url];
}
return NO;
}
return YES;
I don't have it working yet (it's still loading the remote URL) but I think I'm on the right path.
If I use UIWebView to display a phone number and set the data detector type to UIDataDetectorTypePhoneNumber, then when I click on the number its possible to make a phone call.
After the phone call has ended I am returned back to my app.
However if I attempt to programatically invoke the phone app using
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel:123456789"]];
or
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel://123456789"]];
Then it is not possible to return back to my app after the call has finished.
Is it possible to be able to programmatically launch the phone app and then return back to my app after the call is finished, the same as if the user clicks on a number in a UIWebView?
Instead of:
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel://123456789"]];
use:
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"telprompt://123456789"]];
telprompt:// vs. tel://
This will pop up an alert view and the user will have to tap "call" but this returns to the app after the call is done.
Unfortunately, Apple does not allow this to occur, as when you do the openURL command, it will open that application, and since you cannot access anything within that application, you will have to re-enter your application yourself. You can however save your state in NSUserDefaults, and then have the user be able to go back to the same part of the app as when they left. Check here for help: iOS Human Interface Guidelines
use for instance
NSString * telNummer;
NSString *osVersion = [[UIDevice currentDevice] systemVersion];
if ([osVersion floatValue] >= 5.0) {
telNummer = [NSString stringWithFormat: #"telprompt://%#", person.telephoneNumber];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:telNummer]];
} else {
telNummer = [NSString stringWithFormat: #"tel://%#", person.telephoneNumber];
UIWebView *webview = [[UIWebView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
[webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:telNummer]]];
webview.hidden = YES;
// Assume we are in a view controller and have access to self.view
[self.view addSubview:webview];
[webview release];
}
you can send local notification 2-3 seconds after the dial app is visible to the user.
it's not perfect, but clicking on the local notification is and getting back to the original app, its easier the double click on the home button and switch app.
NSURL *url = [NSURL URLWithString:#"telprompt://your phone number"];
[[UIApplication sharedApplication] openURL:url];
This might work?
UIWebView webView = [[UIWebView alloc] init];
NSURL *url = [NSURL URLWithString:#"tel:123456789"];
[webView loadRequest:[NSURLRequest requestWithURL:url]];