Disable hyperlinks in UIWebView - iphone

I want to disable hyperlinks in UIWebVIew after the initial page loaded without disabling the scrolling feature. That is, I should have user interaction enabled.

You can work with webView shouldStartLoadWithRequest like this:
(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
{
NSURL *loadURL = [[request URL]retain];
//change next line to whatever condition you need, e.g.
//[[loadURL relativeString] ....] contains a certain substring
//or starts with certain letter or ...
if([[loadURL scheme] isEqualToString: #"file"])
{
[loadURL release];
return TRUE;
}
[loadURL release];
return FALSE;
}
You also have to set the webViews delegate an object of class where this method is implemented in: [webView setDelegate:my...];
By the implementation above, no url is loaded except those for which the condition is true. At least for the url of the first site it has to be true. The code above works for a web view initially loaded with contents of a file, containing only links to 'http://' or 'https://' or ...

Related

Capturing an specific logout URL in a webView to interact with an embedded html app

I have a simple app, with only a login page. When the user sing-in, I load a webview running an entire html5 app.
The point is that I would like to capture when the user has decided to logout.
Is there any way to listen when a specific url has been loaded?
If so, when the user press logout and the /logout.html would be loaded and I would have the opportunity of returning the control to the iOS app.
Conform to UIWebViewDelegate in your .h file
Set your delegate of UIWebview
Implement the below method:
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSLog(#"URL Request = %#",[[[webView request] URL] lastPathComponent]);
// if (check stringlogout.html) {
// return NO;
// }
// else{
// return YES;
// }
return YES;
}
Check your last component string if it is logout.html then you can do the required stuff and in else you can do what if it is not logout.html action.
Return YES if you want to load the page and return NO if you do not want to load the page.
Good luck with your app...

shouldStartLoadWithRequest doesn't run stringByEvaluatingJavaScriptFromString method

I am trying to run the code below in webview's shouldStartLoadWithRequest delegate method but it doesn't make any changes.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
NSLog(#"webView shouldStartLoadingWithRequest");
[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:#"document.execCommand('bold', false,null)"]];
return TRUE;
}
There is no error, it prints the NSLog and everything in the method works great except "stringByEvaluatingJavaScriptFromString" method.
But if I try to make text bold in another function, for example an IBAction method, works fine.
-(IBAction)boldClick:(id)sender
{
[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:#"document.execCommand('bold', false,null)"]];
}
Actually, this is my company's special application and this UIWebView will not show the web pages. I am using it to show some custom HTML pages.
I need to make everything in "shouldStartLoadWithRequest" because I am trying to run an objective-c method from javascript.
UPDATE
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
// Break apart request URL
NSString *requestString = [[request URL] absoluteString];
NSArray *components = [requestString componentsSeparatedByString:#":"];
// Check for your protocol
if ([components count]==3)
{
[self makeBoldText];
return NO;
}
else
{
return TRUE;
}
}
-(void)makeBoldText
{
[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:#"document.execCommand('bold', false,null)"]];
}
The doc says that method webView:shouldStartLoadWithRequest: is sent before a web view begins loading a frame. After you return YES in this method, web view starts loading a request. So any javascript you execute will have no effect, because a new page will be loaded after your JS call.
You can probably use webViewDidFinishLoad: method to execute javascript after page finishes to load. Or if you want to trigger JS by clicking on a link, you can use shouldStartLoadWithRequest but return NO from it.

prevent to refresh a web page

I have a problem : I have a simple application with a menu and a link that goes to the web page. The web page is: "soundcloud" it is a site that generates music. for example, if I put on a play music and I return to the menu of my application, the music is still running when I return to the web page, the music is still here but the page is returned to zero. and I want to prevent this. sorry for my english I'm french –
Cordialy
Davy
EDIT: This is assuming that the page is contained in a UIWebView within your app. If it's a link that opens in Safari, I don't believe you are going to be able to block navigation in Safari...but in your own web view you can.
Set the controlling class (whichever view controller contains your web view) as a UIWebView delegate. Then, when you implement the delegate protocol:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{ //If you want to block ANY navigation
return NO;
//If you want to block refreshes but allow other navigation
if (navigationType == UIWebViewNavigationTypeReload) return NO;
{
Inspired by #Reid Belton's answer
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
//to prevent reloading html if it is already loaded
if( isHTMLLoaded)
{
return NO;
}else{
isHTMLLoaded = YES;
return YES;
}
}

iPhone UIWebView - Open new UIWebView Controller from a hyperlink

I have an embedded website that has many links but the webview window is fairly small to allow for a larger image above the list to be zoomed in and out. I need the webview to respond to hyperlinks into a new controller view with a second embedded UIWebView if at all possible.
The UIWebView has a delegate wich allows you to respond to certain events, e.g. a request to load new content. Just implement the following in your delegate-class
-(bool) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
//You might need to set up a interceptLinks-Bool since you don't want to intercept the initial loading of the content
if (self.interceptLinks) {
NSURL *url = request.URL;
//This launches your custom ViewController, replace it with your initialization-code
[YourBrowserViewController openBrowserWithUrl:url];
return NO;
}
//No need to intercept the initial request to fill the WebView
else {
self.interceptLinks = YES;
return YES;
}
}

UIWebView loading parsed html string

i'm building an app that will display some newsletters to the users. the newsletters are displayed in a uiWebView. I'm reading the url's for the newsletters from an rss feed. I parse the xml, and in a table view i have all the newsletters. When a cell is clicked the uiWebView is pushed and the newsletter is loaded. Because the uiWebView doesn't open links that have target=_blank i need to replace the _blank from target with "". In an NSOperation i download the contents of the html and after the download is finished i replace the strings like this:
NSMutableString *page = [[[NSMutableString alloc] initWithData:pageData encoding:NSISOLatin1StringEncoding] autorelease]; [page replaceOccurrencesOfString:#"target=_blank" withString:#"target=""" options:0 range:NSMakeRange(0, [page length])];
after i do this i load the parsed string in the webView to display it to the user.
[myWebView loadHTMLString:page baseURL:[NSURL URLWithString:#""]];
while the NSOperation is downloading the contents of the page an HUD with a activity indicator and a label that says Loading is showed. When the download is finished the HUD is removed from the superview.
so far so good..but here come the questions. i used the NSOperation with the callback function because i wasn't able to determine the last call to webDidFinishLoading ( i read this UIWebView - How to identify the "last" webViewDidFinishLoad message? - this is a part of my problem but the response was to use some Apple private classes and that is a problem for me). so i'm doing this:
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
NSURL *url = request.URL;
NSString *urlString = url.absoluteString;
NSLog(#"WebViewSouldStartWithRequest: %#", urlString);
if (navigationType == UIWebViewNavigationTypeLinkClicked)
{
if(![urlString isEqualToString:#"about:blank"])
{
NSLog(#"FeedViewController: startPageLoad");
activityHud = [[HUDView alloc] initWithFrame:CGRectMake(110, 100, 80, 80)];
[activityHud setText:#"Loading"];
[myWebView addSubview:activityHud];
NSLog(#"FeedViewController: pageUrl = %#", urlString);
[self resetWebView];
[urlLoader loadPageFromUrl:request.URL withCallbackTarget:self withCallbackSelector:#selector(endLoading:)];
}
}
return NO;
}
- (void) endLoading:(NSMutableString *)page { [self resetWebView]; NSLog(#"FeedViewController: endLoading"); [activityHud removeFromSuperview]; [myWebView loadHTMLString:page baseURL:[NSURL URLWithString:#""]]; }
after i touch a cell in the table view and the newsletter is showed it looks like it should, when i click a link in the newsletter, the page is loaded with the new request, parsed but visually is not looking as it should (i looked at the page after parsing in NSLog and it has the css styles and html tags, head, body opened and closed correctly) anyone had this problem with uiWebView, not showing webpages correctly?
i tried loading the page with - (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType{ return YES; }
and in - (void)webViewDidFinishLoad:(UIWebView *)webview {} and in - webViewDiStartLoad
but the methods are being called for every item that is loaded in the webview so showing and hiding the HUD in those method is not a good solution.
I encountered some problems while using - (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType { ... return NO }
for example links that have paths like this /bilder-galerien to not work and in NSLog i receive this for them
Unknown scheme, doing nothing:
/bilder-galerien
but when i use
(BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType { return Yes } and didstartLoading and finishLoading the urls are loaded and i don't know why...
another problem are the special german characters..in my first load(after pressing a cell in the uiTableView) the page is parsed like it should be by the uiWebView but after i click a link and the corresponding request is loaded also the characters are not parsed correctly..
can anyone point me in the good direction? thank you in advance
UIWebView doesn't open target="_blank" links. Certain links don't fire UIWebViewNavigationTypeLinkClicked events. This happens when the link has the target="_blank" attribute.
To work around this problem i used the code below. It injects some javascript after the page load to remove the target attribute from all the links. After using this code i didn;t needed anymore to parse the html source and replace _blank with _self for example.
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSString *js = #"\
var d = document.getElementsByTagName('a');\
for (var i = 0; i < d.length; i++) {\
if (d[i].getAttribute('target') == '_blank') {\
d[i].removeAttribute('target');\
}\
}\
";
[webView stringByEvaluatingJavaScriptFromString:js];
}
I like SorinA answer, we can make it even better by:
avoid obstructing javascript with var d
as we know we're running webkit engine we can use selectors:
...so in your UIWebViewDelegate protocol method invoke js code:
- (void) webViewDidFinishLoad: (UIWebView *) webView {
[webView stringByEvaluatingJavaScriptFromString: #"(function($){for(var i=0;i<$.length;++i){$[i].removeAttribute('target')}})(document.querySelectorAll('a[target=_blank]'))"];
}