I am loading a html page using loadHTMLString.
[myWebview loadHTMLString:myHtmlStr baseURL:nil];
Its loading properly. In this html web page, i'm also adding buttons, drop down(with selection) etc. I want to catch the action events in my code now for these web page controls. For example, from the drop down if user chooses an option, i need to add another 'textarea' dynamically in the same web page. and, if user clicks on a button(button from the webview), i need to handle some events. I would like to know, how to do some tasks under the events triggered for controls in web view which is generated by my string.
Could someone please advise me.
to handle event on button in webview load a url in webview for ex:http://button1clicked and then in webView:shouldStartLoadWithRequest:navigationType: method check if the url is button1clicked then return no and also perform your action which you want to do on button clicked.
for example:
write this in webView:shouldStartLoadWithRequest:navigationType: method.
if([[[request URL] absoluteString] isEqualToString:#"http://button1clicked"])
{
//perform you action you want to do
return NO;
}
and on button click call javascript function window.location='http://button1clicked';
The documentation clearly states that UIWebView is not intended for Sub-Classing. However, you can still detect all the events.
But maybe this will help : Tutorial
Related
I have a webview loading a website with a html form. When the user has entered their login credentials and push submit-button the user is sent to a new view controller. I want to stop this from happening IF the user enters the wrong credentials. If the wrong credentials are entered the website adress remains the same. Can I somehow say:
if (navigationType == UIWebViewNavgiationTypeLinkClicked) {
if (url remains the same == alert view saying wrong credentials was entered.
if (url changes - perform segue to new view controller?
Let your controller implement UIWebViewDelegate. When you do that, a bunch of callbacks will be called at different phases of the web request. The one you probably want to implement is this one:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
// Be sure to use mainDocumentURL, because any iframes on your form page will
// also trigger this callback
NSString *completedurl = webView.request mainDocumentURL.absoluteString;
// Let's assume you have your form url in the string property self.formurl
if ([completedurl isEqualToString:self.formurl]) {
// Display your alert view saying that the credentials were incorrect
} else {
// Perform segue to next controller
}
The whole solution is a bit scary though, because any other error page or whatever would
trick your app to believe that the user was successfully logged on. A better approach might
be to check the html contents of the webview for some significant string that the
successful-login-page contains. You can get the html body by calling:
NSString *yourHTMLSourceCodeString = [webView stringByEvaluatingJavaScriptFromString:#"document.body.innerHTML"];
Yet another approach is to look for a cookie in the webview that confirms the login.
Or even better, use a native login form, submit the login request with native code, using
AFNetworking or the standard http SDK methods, and check the response for success.
A general question on UIWebViews. I have a single webview in my app. There are buttons on the left which simply load up different URLs into the webview.
Are there any ill consequences to loading a new URL into the webview without [webview stopLoading] the previous request first?
For example, this flow could happen:
User presses button1 to load urlA into the webview
While urlA is still loading, user presses button2 to load urlB into the webview
But would this better?
User presses button1 to load urlA into the webview
While urlA is still loading and user presses button2 for urlB
First call [webview stopLoading], then proceed to load urlB.
Are there any best practices for such a scenario? Does it matter either way?
Thanks!
According to the documentation, stopLoading has to be called before the view is going to disappear or be destroyed. This implies that an asynchronous event would just survive, potentially causing havoc.
However, no mention is made of your scenario. I would still call stopLoading just do be on the safe side. If the loading property of the web view is NO, this method simply does nothing.
I have a form in the UIWebView to interact with a web service, when I submit the form, the data gets sent to a web service and it will return the result to another UIWebView. The two UIWebViews are under a navigation controller, so when the use submits the form, it slides to another view to display the result. Can anyone point me out how I can achieve this? What do I fill in the "action" attribute in the form element? How can I get the user input back to the application so I can use the web service? I am new to this field, any help will be appreciated. Thanks!
Update:
Is there a way to save form data from web view back to my program? I think it's better to save form data back to the program (i.e. store params into nsstring) when I click submit button, and then start querying web service.
You can use the
stringByEvaluatingJavaScriptFromString
function for firing a javascript method from objective c and get a return value from that method.
For example
//Calling the getTheUsername in the javascript.
NSString *userName = [yourWebView stringByEvaluatingJavaScriptFromString:#"getTheUsername()"];
and in javascript
//Method in javascript
function getTheUsername()
{
return userNameVariable;
}
And I doubt that here you may wanna do vice-versa (Call obj-c method from javascript). This cannot be done directly here is the work around.
Set a UIWebViewDelegate, and implement the method webView:shouldStartLoadWithRequest:navigationType:. In your JavaScript code, navigate to some fake URL that encodes the information you want to pass to your app, like, say:
window.location = "someLink://yourApp/form_Submitted:param1:param2:param3";
In your delegate method, look for these fake URLs, extract the information you need, take whatever action is appropriate, and return NO to cancel the navigation.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
NSLog(#"%#",[[request URL] query]);
return YES;
}
If I understood your problem correctly, I think following steps will help you to provide the solution.
In the action of form, you need to write the URL to the web service.
In your form, the name of the input field should be matched with the name of the parameters expected for the web service.
In your first UIWebView Navigation control, Create the object of screen having second UIWebView and set the response of the web service to the instance member of the object.
In your first UIWebView Navigation control, you need to write
[self presentModalViewController:webView2Object animated:YES];
In the screen of having webView2, parse the response before loading the second UIWebView. and inject it with the displayed page using javascript.
Web presenting a website in a UIWebView, the user can touch links.
When testing [[webView.request URL] absoluteString]in didFailLoadWithError or webViewDidStartLoad, it returns the previous url. The touched url is shown in webViewDidFinishLoad
If the user touches a link, and the connection fails, how may I know where he was going to as webViewDidFinishLoad is not triggered ?
Immediately after the link is tapped, -webView:shouldStartLoadWithRequest:navigationType: is called in your delegate. That gives you a chance to inspect the request and what kind of navigation action triggered it (link, back/forward, form post...).
I have a WebView which is loading and HTML String and I want it to catch clicks on links.
For that I need to use the webView:shouldStartLoadWithRequest:navigationType method.
The problem is that this method gets called multiple times before the HTML content is fully loaded and I only want to start catching clicks at that moment.
The question is how to know when the HTML content is fully loaded ? I thought it was simple so I created a boolean as an iVar of the ViewController containing the WebView and I set it to YES after calling loadHTMLString. Then, in webView:shouldStartLoadWithRequest:navigationType I was testing if that boolean was true and if it was the case I was outputting something like "OK". But "OK" was appearing without clicking on a link => fail.
Any idea on how I could make this work ?
Thanks in advance
You could use the webViewDidFinishLoad: delegate method to know when the HTML is loaded.
But I'd rather use another solution:
In webView:shouldStartLoadWithRequest:navigationType: you can filter requests by navigation type:
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
// Catch links
return NO; // if you want to cancel the request, else YES
}
- (void)webViewDidFinishLoad:(UIWebView *)webViews{
}
this method will callwhen the HTML content is fully loaded.
it may helps you.