I have an IBAction on a button with the following code that I am trying to use to retrieve the source code of a UIWebView:
- (IBAction)loadInAWebView:(id)sender {
[self.webView loadHTMLString:[NSString stringWithFormat:#"Hello: %#", _name.text] baseURL:nil];
NSString *yourHTMLSourceCodeString = [_webView stringByEvaluatingJavaScriptFromString:#"document.documentElement.innerHTML"];
NSLog(#"%#", yourHTMLSourceCodeString);
}
The use of the code above is from the reference I saw at this link: Getting the HTML source code of a loaded UIWebView.
However, the NSLog function always returns the following:
<head></head><body></body>
This obviously does not reflect the actual source code of the UIWebView that in my mind should be:
<head></head><body>Hello, name</body>
Indeed, the UIWebView returns the "Hello, name" content but the related source code does not.
How can I edit the code above to retrieve the real UIWebView source code?
You need implement UIWebViewDelegate methods - (void)webViewDidFinishLoad:(UIWebView *)webView and set self.webView.delegate = self; Put your code NSString *yourHTMLSourceCodeString = [webView stringByEvaluatingJavaScriptFromString:#"document.documentElement.innerHTML"]; to this method
Related
i have created webview in my app,
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:#"SimpleCall" ofType:#"html"];
NSString* htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:nil];
[webview loadHTMLString:htmlString baseURL: [[NSBundle mainBundle] bundleURL]];
[self.view addSubview:webview];
now i want to send a data to webview when webview starts load.is there any property for uiwebview?
thanks advance.
you must set the delegate UIWebViewDelegate property on your UIWebView, for example:
webView.delegate = self;
where self conforms to UIWebViewDelegate protocol and implement callback method webViewDidStartLoad (check docs) if you really want to do something when web view starts load. Then, you implement the method:
- (void)webViewDidStartLoad:(UIWebView *)webView {
//you can do something in here, but DON'T call any loaders of webView's - loadHTML or reload, cause this will result in a loop
}
But I doubt that will solve your problem - first of all you probably want to do something when web view finishes. Second - can you elaborate more on what you mean by:
send data to web view
DISCLAIMER: as of iOS 8 and higher you should use WKWebView instead.
EDIT: as clarified in comments you want to update dynamically html contents. In WKWebView docs you can read that there is no option to do that (i.e. dynamically insert options from your NSArray to loaded html string). You have to manually update your html string and then reload WKWebView with new, updated html. Reloading whole html just to update one feature is probably not an option here, so better store the webpage loaded on the server and update dynamically (when web page is updated with new options) by calling:
[webView reload];
I want to use a simple WebView to fetch the content of a website, which includes JavaScript. I don't want to really show the WebView, I only want to get the source code of the site. The view where I will load the request from, is not in the window hierarchy. The method is getting called from another view.
Something like this:
MainView.m:
[[HelperView alloc]LoadWebview];
HelperView.m:
-(void)LoadWebview {
webView = [[UIWebView alloc]init];
[webView setDelegate:self];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.google.com/"]]];
[self.view addSubview:webView];
}
Is it possible to use the delegate methods from this WebView in a view, which is not in the window hierarchy, or is there a better way to solve this problem?
If all you need is to get the source code then try this:
-(void)loadWebview{
//Create an NSURL object
NSURL *url = [NSURL URLWithString:#"http://www.yourWebsiteHere.com"];
//Create a string to hold the source code
NSString *sourceCode= [NSString stringWithContentsOfURL:url];
//Do what you want with the source code here!
}
I have a UIWebview as a sub view of a custom view. I have used XIB's for Custom Views. So the hierarchy is as follows:-
ViewController.view -(subview)> SettingsCustomView -(subview)> TermsCustomView -(subview)> UIWebview (in XIB).
I have connected the the delegate method as well as the Outlet perfectly. Everything loads and happens as it should be, and even the methods getting called perfectly without error. Only one thing is missing, content for webview. Its like the content is loading but is not visible.
I did these but none of them shows the content although it loads the content :-
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:#"terms" ofType:#"html"];
NSString* htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:nil];
[self.termWebView loadHTMLString:htmlString baseURL:nil];
and I also tried this :-
[self.termWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.google.com"]]];
All the delegate methods getting called the html string is perfect in the first case. Its just that the content seems to be invisible.
Thanks in advance for any help.
Finally I resolved this by adding the delegate method of UIWebview and returning TRUE as follows:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
return YES;
}
I declared my App (a rich text editor) to be able to open any RTF file (coming, for example, from an email attachment). The application delegate sends a "loadContent: (NSURL *) url" message to the UiwebView controller when the user select the attachment. In the receiver, I get the url and load the RTF file in the UIWebView using
- (void) loadContent: (NSURL *) passedURL
{
if (passedURL) {
[self.myWebView loadRequest:[NSURLRequest requestWithURL:passedURL]];
} else {
NSBundle *bundle = [NSBundle mainBundle];
NSURL *indexFileURL = [bundle URLForResource:#"index" withExtension:#"html"];
[self.myWebView loadRequest:[NSURLRequest requestWithURL:indexFileURL]];
}
}
Doing that, everything goes all right, and "myWebView" displays the content of the RTF file. The problem is that this view should be content editable, and the code should contain some javascript that I have in my "index.html" bundled file. I load when starting application. So I added some code to extract the HTML code created from the RTF file to be able later to recreate a complete code, inserting the extracted code in a tag like that:
<div id="content" contenteditable="true"> imported html from rtf should be there</div>
I modified the loadContent method to get that.
- (void) loadContent: (NSURL *) passedURL
{
if (passedURL) {
[self.myWebView loadRequest:[NSURLRequest requestWithURL:passedURL]];
NSString *dum=[self.myWebView stringByEvaluatingJavaScriptFromString:#"document.body.innerHTML;"];
NSLog(#"%#",dum);
} else {
NSBundle *bundle = [NSBundle mainBundle];
NSURL *indexFileURL = [bundle URLForResource:#"index" withExtension:#"html"];
[self.myWebView loadRequest:[NSURLRequest requestWithURL:indexFileURL]];
}
}
Looking to the result of the NSLog, I get only the following html
<div id="content" contenteditable="true">Hello folks</div>
Which was the HTML content of myWebView BEFORE I loaded the rtf file...
Do you have any idea of what is going on? Why does dum displays the former code, as the displayed myWebView displays the new one? Is it because the loadRequest is executed in a separated thread and that when executing the next instruction, myWebView still contains the former code?
Thanks
[EDITED] I also tried to NSLog the content of the webView in webViewDidFinishLoad: delegate method, but get the same result: the content of this webView before I opened the RTF attachment file. Is It possible to make a load request in a synchronous way?
This is because loadRequest is asynchronous. You need to wait for the load to finish before trying that NSLog. Take a look at the UIWebViewDelegate docs. Try that NSLog inside/after webViewDidFinishLoad: and you should get better results.
I am very new to the whole programming business, and was wondering if there is any way to clear the contents of a UIWebView in iphone programming, so that the loading symbol for the next view is not showing up in front of the last view.
Many Thanks,
Thomas
Try setting the URL to about:blank and reload the page.
Just load an empty html string into it
[self.webView loadHTMLString:#"" baseURL:nil];
Answer extension for documentation purposes to maybe help someone else:
I had the same desire (clear content before loading next url) but had a UIWebView delegate set to receive webviewDidFinishLoad:(UIWebView)webview message and update another part of UI in response.
Problem: the call to clear the content to also called delegate method, so getting false-hits (that is, getting call when clear is done, too, but delegate is coded to expect call only when real content is loaded).
Solution: use a known URL for clear, and have webviewDidFinishLoad: ignore calls made when that URL is finished:
- (void) startLoadOfNextURL:(NSURL*)url
{
// clear:
[self.webView loadHTMLString:#"" baseURL:nil];
// Load real next URL
NSURLRequest* request = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:request];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSLog(#"WebView finished loading: %#", webView);
if ([self.webView.request.URL.absoluteString isEqualToString:#"about:blank"]) {
NSLog(#" This is Blank. Ignoring as false event.");
}
else {
NSLog(#" This is a real url");
[self updateUIInSomeWay];
}
}
Note: using this:
[self.webView loadHTMLString:#"about:blank" baseURL:nil];
actually causes the words "about:blank" to appear as text in the webview's content pane!
Final complication: In practice, with my two [webview load...] calls so close together, I was finding that instead of a "loaded" event for the clear, the webview was actually canceling it in favor of the second request and calling webView: didFailLoadWithError: for the first load request. Thus, I had to put similar code in that event:
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
NSLog(#"WebView error on: %#", webView);
NSLog(#"Error is: %#", error);
NSURL* failingURL = [error.userInfo objectForKey:#"NSErrorFailingURLKey"];
if ([failingURL.absoluteString isEqualToString:#"about:blank"]) {
NSLog(#" This is Blank. Ignoring.");
}
else {
NSLog(#" This is a real URL.");
[self doSomethingAboutError];
}
}
Swift, Xcode 7 beta 5
webView.loadRequest(NSURLRequest(URL: NSURL(string: "about:blank")!))
Swift 4.0 , XCODE 9
webView.loadRequest(URLRequest.init(url: URL.init(string: "about:blank")!))
Same answer in Swift 4.2, xCode 10
if let clearURL = URL(string: "about:blank") {
myWebView.loadRequest(URLRequest(url: clearURL))
}