How to inject JQuery into existing page within a UIWebView? - iphone

I am trying to inject JQuery into a UIWebView of a page that I can't control, say Google, for example. When a UITextField gets focus, I am executing the following lines of code:
NSString* scriptInject = #"var headElement = document.getElementsByTagName('head')[0]; var script = document.createElement('script');
script.setAttribute('src','http://jquery.com/src/jquery-latest.js');
script.setAttribute('type','text/javascript'); headElement.appendChild(script);";
[myWebView stringByEvaluatingJavaScriptFromString:scriptInject];
[myWebView stringByEvaluatingJavaScriptFromString:#"$(document).ready(function() {$('body').css('background', '#FF0000');}"];
I am executing the background change to validate that I am able to run a JQuery script. I can verify that the Objective-C method is being called, and I even planted an alert for the onload of the newly created <script> tag, so I know that it is being executed in the UIWebView. How do I inject it correctly that I can execute it?
EDIT:
I have event tried this after calling the function to change the color:
[myWebView stringByEvaluatingJavaScriptFromString:#"alert($('body').css());"];
No alert shows.

This has worked for me:
NSString *jqueryCDN = #"http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js";
NSData *jquery = [NSData dataWithContentsOfURL:[NSURL URLWithString:jqueryCDN]];
NSString *jqueryString = [[NSMutableString alloc] initWithData:jquery encoding:NSUTF8StringEncoding];
[webView stringByEvaluatingJavaScriptFromString:jqueryString];
[webView stringByEvaluatingJavaScriptFromString:/*jquery commands here*/];
Taken from this article.

If jQuery is not in the DOM already you can use stringByEvaluatingJavaScriptFromString: to inject it. I've had similar problem, I wrote a blog post about it: HTML parsing/screen scraping in iOS.

Related

Slow loading UIWebView from string

I am trying to load a UIWebView from a string as follows:
NSString* plainContent = #"...";
NSString* htmlContentString = [[NSString stringWithFormat:
#"<html>"
"<style type=\"text/css\">"
"body { background-color:transparent; font-family:Arial-BoldMT; font-size:18;}"
"</style>"
"<body>"
"<p>%#</p>"
"</body></html>", plainContent] retain];
[webView loadHTMLString:htmlContentString baseURL:nil];
Where plain content has some simple HTML with about 5 links and 400 characters. I'm trying to run this on my iPhone5, and the first time it loads it always take a few seconds. Does anyone know why this is happening and how to fix this?
I recently struggled with UIWebView performance. It seemed to take a very long time to process the local HTML I was providing (1 or 2 seconds on iPad Air 2 simulator) even if it was ridiculously small.
After a lot of googling around, I found that the culprit was the phone numbers detection on webview. Once I unchecked it on the storyboard, the latency was gone.
Hope it helps someone facing the same issue :)
This usually happens because of CSS used in rendering web page. It is default behavior when loading page locally. We can also consider that in first load, UIWebview doesn't have cache to this and create cache for that page.
To make it little fast try loading page from a file e.g.
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"filePath" ofType:#"html" inDirectory:#"."]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
CSS like body { background-color:transparent; font-family:Arial-BoldMT; font-size:18;} also increase the time of loading a page.
For other who experienced this problems, sometimes we created HTML file by copy-paste-ing from existing websites and we're forget to check the links on header.
In my case, I forgot to remove unused link rel in my html string header:
NSString* html = [NSString stringWithFormat:#"<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><title>%#</title><link type=\"text/css\" rel=\"stylesheet\" href=\"http://192.168.3.183/assets/css/question.css?1383042738\" /></head><body><h1 style=\"font-size: 2em; margin-bottom: 0; color: #3357b8; font-weight: bold\">%#</h1><div style=\"color: #555\">%#</div><br><p style=\"line-height: 1.7em\">%#</p><b>Open in browser</b><br></body></html>", title, title, dateString, content, detail];
The local URL pointed by above link rel make loading time even worst.
<link type=\"text/css\" rel=\"stylesheet\" href=\"http://192.168.3.183/assets/css/question.css?1383042738\" />
Just don't forget to re-check your header or other link in your HTML string and remove it if it is not used.
In case of WKWebView, disabling WKWebView's data detectors worked for me. Swift version:
let webViewCofig = WKWebViewConfiguration()
webViewCofig.dataDetectorTypes = []
webView = WKWebView(frame: view.frame, configuration: webViewCofig)
To enable specific data detector, pass the specific type as .address,.link etc while setting dataDetectorTypes:
config.dataDetectorTypes = [.address]

xcode UIWebView loader code HTML

I've a question about load inside the web view:
I create a Json file to get Wordpress table and work well but inside the content table i can get only pure HTML code in one Line, so if i do a request from the web view to load the content like standard code i can't see the content, but only pure code with tags:
[MyWeview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:MyJsonClass.MyContentTeble ]]];
This normal code working, but not to encode HTML, i will get code like:
NSString *HTMLData = #"<iframe></iframe>";
[palinsesto loadHTMLString:HTMLData baseURL:nil];
But my code #"" is get from MyJsonClass.MyContentTable
Thanks for help.
//---------------------------------------------------------------------//
Thx for you answer White, but still not working, if i try to use that code:
[MyWebview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:MyJsonClass.MyContentTeble ]]];
Working, but i cant see the content.
I try your code and built app good, but crash after touch UITable Cell.
Think i need a Encoder inside the App to read and compile like a NormalWebBrowser a simple HTML code, but never <html><body></body></html> tags T_T because i get pure code and tex from WordPress Table on Mysql DB.
Any other idea?
you might try the following:
[web loadHTMLString: # "<html> <body> <iframe src = 'http://www.example.com', style = 'border-width: 0' width = '100% 'height = '480' frameborder = '0 'scrolling =' no '> </ iframe> </ body> </ html> "baseURL: nil];
- (BOOL) WebView: (UIWebView *) WebView shouldStartLoadWithRequest: (NSURLRequest *) request navigationType: (UIWebViewNavigationType) {navigationType
if ([request.URL.absoluteString rangeOfString: # "www.example.com"]. location! = NSNotFound) {
NSLog (#"%#", [WebView stringByEvaluatingJavaScriptFromString: # "document.body.innerText"]);
return NO;
}
return YES;
}
This is an idea.
I hope you can help

problems showing the actual URL of a page in my app

I'm making an iPad browser, and I have a little problem. When I go to google, for example, I write the google direction in a textField. The problem is that when I change the web page, it still says http://www.google.com/. Here's my code:
-(IBAction)buttonpressed2:(id)sender {
url = [NSURL URLWithString:[textField text]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
[webView isEqual:textField.text];
}
How can I make the textField show the page that I'm watching right now, and not the first url typed in the field?
First, make sure when you set up the webView, you assign the UIWebViewDelegate to self
Then, implement the delegate method: webViewDidFinishLoad, as such:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSURLRequest *currentRequest = [webView request];
NSURL *currentURL = [currentRequest URL];
//This will log the current url
NSLog(#"Current URL is %#", currentURL.absoluteString);
//Then to display it in the textField
textfield.text = currentURL.absoluteString;
}
Edit:
A delegate is a special set of methods that wait for an event to happen. When that event happens, the appropiate method is called. The method above is one of the delegate methods for a UIWebView - When a specific event happens with the webView, in this case when the webViewDidFinishLoad, that method is automtically called and we can respond as such. In order to set the delegate, we can proceed one of two ways:
If you created the webView in code, this is with something like this:
UIWebView *webView = [[UIWebView alloc] init...]
then all you need to do is add the following line of code:
webView.delegate = self;
However, you might have also created the webView in the interface builder - If that's the case, click on the webView and the linker tab, and drag the delegate option over to "File's Owner".
and thats it.
Your class should implement the UIWebViewDelegate protocol. Then in the method webView:shouldStartLoadWithRequest:navigationType: you can do this:
[textField setText:[[request URL] absoluteString]];
This way the value in the textField will be updated whenever you navigate to a new url.

UIWebview manipulating SVG 'on the fly'

I would like to know how to manipulate SVG files that I have loaded into a UIWebview. Currently I am loading an SVG file into an HTML file and then loading that into a UIWebview. I presume that you would use Javascript to do this but am not sure how the go about it exactly. Ideally I would like to be able to manipulate the SVG on the fly in an iPad app. I am aware that you can 'inject' code into the UIWebview but have had no success with my attempts. Clear as mud? Well perhaps a bit of code will help.
Here is how I load the html file into the UIWebview inside the view controller .m file:
- (void)viewDidLoad
{
[super viewDidLoad];
NSString* path = [[NSBundle mainBundle] pathForResource:#"SVG" ofType:#"html"];
NSString* content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
webView = [UIWebView new];
webView.frame = CGRectMake(0, 0, 1024, 768);
webView.dataDetectorTypes = UIDataDetectorTypeAll;
webView.userInteractionEnabled = YES;
[webView loadHTMLString:content baseURL:[[NSBundle mainBundle] bundleURL]];
[self.view addSubview:webView];
[webView release];
}
Here is the code inside the html file that is loaded into the UIWebview:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>SVG</title>
</head>
<body>
<object id="circle" data="Circle.svg" width="250" height="250" type="image/svg+xml"/>
</body>
</html>
...and finally here is the code inside the SVG file:
<svg xmlns="http://www.w3.org/2000/svg">
<circle id="redcircle" cx="200" cy="50" r="50" fill="red" />
</svg>
Which creates a nice little red circle in the UIWebview. Now I would like to be able to manipulate the circle on the fly back in the view controller .m file. For example when the user touches the iPad screen, change the fill color attribute to green. Is this even possible?
I hope this all makes sense. It's a bit convoluted. But ultimately what I am trying to do is create graphics on the fly with SVG in an HTML framework and display it in a UIWebview.
Any help would be appreciated. Thanks.
You can execute arbitrary Javascript by passing it to stringByEvaluatingJavaScriptFromString on the webView at any point after the page has first loaded - like in response to a touch event.
So if the Javascript to find the SVG object and change the color looks something like (YMMV, haven't actually tested this):
var path=document.getElementById("circle").getSVGDocument().getElementById("redcircle");path.style.setProperty("fill", "#00FF00", "");
You can execute it with:
NSString *string = #"var path=document.getElementById('circle').getSVGDocument().getElementById('redcircle');path.style.setProperty('fill', '#00FF00', '');";
[webView stringByEvaluatingJavaScriptFromString:string];

entity nbsp not defined

I have been trying to load the url http://friscotxcoc.weblinkconnect.com/cwt/External/WCPages2/wcevents/eventsstartpage.aspx?oe=true&ce=true into a webview but it shows up an error 'Entity nbsp not found'.
The link works properly over Safari (Machine as well as simulator) but doesnt load properly when loaded through a webview. Can someone point me as to how to do it?
#define kEventsCalenderLink #"http://friscotxcoc.weblinkconnect.com/cwt/External/WCPages2/wcevents/eventsstartpage.aspx?oe=true&ce=true"
NSURL *eventsURL = [NSURL URLWithString:kEventsCalenderLink];
eventsWebView.delegate = self;
[eventsWebView loadRequest:[NSURLRequest requestWithURL:eventsURL]];
The server is serving that page with the Content-Type of "application/xhtml+xml" to the Simulator version of Safari. Safari is interpreting the page as strict XML, which does not have an entity.
Unfortunately, UIWebView manipulates its HTTP headers behind the scenes, and it's seemingly impossible to configure it to make a request that will cause your server to serve content as "text/html"
The one workaround I would suggest is to retrieve the content with an NSURLConnection, then feed it to your web view with the loadData:MIMEType:textEncodingName:baseURL: method, being sure to pass "text/html" as the MIME type.
This may also necessitate intercepting future requests via the webView:shouldStartLoadWithRequest:navigationType: delegate method (in order to cancel them and load them in the manner described above to prevent similar problems).
Or, if you have control of the server, you could configure it to serve HTML with the appropriate content type. Or convert the content to use proper XML entities.
Do it in this way:
NSString *kEventsCalenderLink #"http://friscotxcoc.weblinkconnect.com/cwt/External/WCPages2/wcevents/eventsstartpage.aspx?oe=true&ce=true"
NSLog(#"%#",kEventsCalenderLink);
eventsWebView.delegate = self;
eventsWebView.userInteractionEnabled = true;
[eventsWebView loadRequest:[[NSURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:kEventsCalenderLink]]];
You have only defined the URL which you haven't mentioned that it's string type.
Here is the sample code which i implemented.Hope it would help you
- (void)loadView
{
UIView *vew=[[UIView alloc]initWithFrame:[[UIScreen mainScreen]bounds]];
self.view=vew;
//self.title=#"sanjay";
//self.navigationItem.title=#"afdsfasd";
self.view.backgroundColor=[UIColor redColor];
[vew release];
UIButton *smsbtn=[UIButton buttonWithType:UIButtonTypeRoundedRect];
smsbtn.frame=CGRectMake(50, 280, 100, 50);
[smsbtn setTitle:#"SMS APP" forState:UIControlStateNormal];
[smsbtn setTitleEdgeInsets:UIEdgeInsetsZero];
[smsbtn addTarget:self action:#selector(loadsms) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:smsbtn];
}
-(void)loadsms
{
NSString *url = [NSString stringWithFormat:#"http://friscotxcoc.weblinkconnect.com/cwt/External/WCPages2/wcevents/eventsstartpage.aspx?oe=true&ce=true"];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: url]];
}
This code is working dude.Try this out.I have implemented this for you only.