getting image from UIWebView - iphone

I am loading a web page inside a UIWebView, clearly a web page has many images in it. I am loading it to the UIWebView via
- (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL
the issue is that this doesn't trigger the NSURLCached which I have subclassed. I basically want to cache the data I get when the UIWebView loads the <img src = ""> tag so I can use it later on for faster loading or such. Is there any way to do this?

Yes, this should actually work. Did you set your cache globally via NSURLCache's
+ (void)setSharedURLCache:(NSURLCache *)cache
before loading the HTML?
Maybe you would like to have a look at Matt Gallagher's NSURLCache Tutorial, which shows an example of a subclassed NSURLCache which does pretty much what you're asking for (serving stored images for certain requests).

Related

How to apply local styles / JS to UIWebview after loading a URL

I am loading a web page in my iPhone app. However the page is not mobile optimized. So, I would like to customize some elements from the page like remove sidebar etc.
For doing this, I guess, some CSS / JS need to be injected into the page to modify the page. Can this be done ? If yes, how to?
Any help appreciated.
For others having same question:
It can be done by using stringByEvaluatingJavaScriptFromString: method of UIWebView (upon webViewDidFinishLoad)
-(void)webViewDidFinishLoad:(UIWebView *)webView {
[webView stringByEvaluatingJavaScriptFromString:#"document.getElementById('topBarBody').remove();"];
}

text and image as one scrollable entity

I need an undefined amount of text and one or more pictures to be scrollable as one entity. I'm quite surprised that this doesn't seem to be provided by default, I thought I've seen that several times before... I tried to google, but all I find doesn't fit. The images won't be wider than the screen, but in between lines of text.
I need something that let's me do something like:
image
textA
textA goes on
__ screen ends here, content goes on
textA goes on
textA goes on
image
image
textB
textB goes on
image
textC
The content for the text would come out of a plist, but I THINK I can predict it will be REALLY static, so I could just set the Text in IB and create a view for every content -.-.
I've read about Web View, but as far as I got it, you'd need internet connection to make that work, and the app should work without any internet connection at all.
Any suggestions or experiences concerning that?
Thanks a lot!
There different way to get things done:
If you have static content and want a complicated layout and know how to do it in html you should go with UIWebview and a bundled html file and images and load it with something like:[webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"MyStuff" ofType:#"html"]]]];
You can also do a layout with UILabels and UIImageviews and arrange all of this onto one UIScrollview
If it's more dynamic you should go with the latter, but you need to program sort of layout algorithms that handle different number/sizes of images, number/length of test paragraphs and so on.
One option, as you mention, is UIWebView.
It does not require a connection, since you can load a static HTML into it executing:
– loadHTMLString:baseURL:
By specifying a baseURL that "points" to your bundle, you can also include images as resources in your Xcode project and have them displayed (by using <img src=... /img in your HTML):
NSString* basePath = [[NSBundle mainBundle] bundlePath];
[_label loadHTMLString:text baseURL:[NSURL fileURLWithPath:basePath]];
You don't need an internet connection to make a web view work. Look at this method on UIWebView:
- (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL

Programmatically Generate PDF from HTML on iPhone

I am looking for a way to programmatically (in obj-c) generate a PDF file from a local html file. I am dynamically generating the html from user inputs, I need to create the PDF and send it to the user (via email). I am having difficulty with the PDF generation portion.
I have the code to create a PDF using CGPDFContextCreateWithURL but I am struggling with drawing the page using quartz.
I have searched extensively on SO as well as the internet to no avail.
Any help is much appreciated!
To generate a pdf from an HTML, you need to render the html into a web view, and take snapshots of the web view, and render them into an image context.
The tutorial might be helpful:
http://www.ioslearner.com/convert-html-uiwebview-pdf-iphone-ipad/
I've written a little piece of code that takes an NSAttributedString from DTCoreText, and renders it into a paged PDF file. You can find it on my GitHub Repository. It won't render images or complex html, but it should serve for most uses. Plus, if you're familiar with CoreText, you can extend my PDF frame setter to generate these items.
So what it does now: Give it an HTML string, and it will use DTCoreText to generate an NSAttributedString, then render that into a PDF. It hands back the location that it saved the PDF file in the app's Documents folder.
Why not use a WebService, send the HTML page to this and retrieve the PDF-file ?
That way you can use iTextSharp and C#, and you're done in about 2 minutes.
Plus (if you're evil) you can store and see all the data on your server.
I haven't tried this myself so i have nothing to offer concrete but I'd have to imagine there has to be an easy way to do this on iPhone due to the imaging model. I'd look deeper into the documentation.
As to pushing back with the client that is up to you but there are probably multiple reasons for wanting to keep everything local. Frankly I would not be pleased at all to here from somebody I hired that he couldn't manage this particular task. So think long and hard about this push back. Oh even if you do push back a webserver is a poor choice. I'd go back a step further and investgate why you need something in HTML in the first place.
I've never tried this so I have no idea if it'll work, but how about loading the HTML into a UIWebView, and then make the view draw itself into a PDF context? E.g.
UIWebView *webview = [[UIWebView alloc] initWithFrame:CGRectMake(...)];
[webview loadHTMLString:html baseURL:...];
Then:
- (void)webViewDidFinishLoad:(UIWebView *)webview {
CGPDFContextRef pdfContext = CGPDFContextCreateWithURL(...);
[webview.layer drawInContext:pdfContext];
...
}
I made it by following this SO: https://stackoverflow.com/a/13342906/448717
In order to maintain the same content's proportions I had to multiply the size of the WKWebView 1.25 times the printableRect's size set for the UIPrinterRenderer, as the screen points differs from the PostScript's... I guess.

iPhone UIWebView slow loading to local HTML files

I'm developing an app that requires caching web pages (completely) along with their CSS files and images after saving the entire HTML of the page (going through the links to store each file along with the HTML file).
While viewing the HTML file offline, UIWebView takes a long time to load the page, given that I'm already offline, and the file is on disk along with its CSS and images.
I'm using this code to load the file:
NSData *htmlData = [NSData dataWithContentsOfFile:htmlFilePath];
[wView loadData:htmlData MIMEType:#"text/html" textEncodingName:#"UTF-8" baseURL:[NSURL fileURLWithPath:self.htmlFolderPath isDirectory:YES]];
Is there any other means of loading the file to the UIWebView that can load it faster?
P.S: it loads very fast on simulator (offline) but on device it takes a long time (considering its an already offline cached file)
Thanks for help.
Is your solution actually cache things other than the html file, meaning pictures, css, etc, AND relinking them in the html page? I am guessing that you are downloading and caching the html page and external resources then the UIWebView is loading that html and still going out to load the external resources. That would explain the fast performance on the simulator and the slower performance on device.
Here is a library designed to do exactly what you are trying to do: ASIWebPageRequest.
It should also be noted that it could simply be a case of disk i/o bottlenecking. I know on my project, I was loading large images in a uitableview and even after they were cached I noticed quite a bit of lag when pulling them off the disk because they were so big.
I've found certain kinds of CSS can grind WebView rendering to a halt. For example:
body { -webkit-box-shadow:inset 0 0 100px #222; }
This works great in the simulator, looks nice too. But on the phone (even the iPhone 4, iOS 4.2), a simple page will take 10sec to render.
Since this probably just takes time because it needs to parse and render the page, you may consider firing up the UIWebView in the background; i.e. added as a subview, but not visible.
Maybe the UIWebView is smart enough to know it doesn't need to do anything, but I suspect that at least html and css parsing is done right away.
If it doesn't do anything without being visible, reduce size to 1x1 and set opacity=0, and put that pixel some place where it can't interfere with touch event handling.
Not perfect but it may work.
I'm almost sure you will never be able to do this. The UIWebView just needs some time to process your webpage even when it's a local page.
Keeping that in mind you can try to preload the page before it's being shown. For example if you show it after a user presses a button, preload the page when you show the button instead of when the user actually presses the button. The user doesn't notice the slow loading, because it's being handled in the background so when the user presses the button the page is already been loaded.
I can give you an idea about alternative ways of loading HTML from file into the UIWebView. A small project I've got uses Objective-C as a pure wrapper for UIWebView
The project is here, but the main code is below: http://github.com/robb1e/iWeb
- (void)viewDidLoad {
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"test" ofType:#"html" inDirectory:#"."]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
[super viewDidLoad];
}
I'm also exploring ways of improving the perceived performance by showing an image while the DOM is getting ready. Some answers I've had are here:
Displaying a background image on UIWebView
Just if in case someone happens the same to me...
I had a UIWebView that was loading a string html and every resource (js and css) was stored locally.
I've faced that loading the content with internet connection it was some kind of slow (1 or 2 seconds to load and appear the webview in my controller) but when I tried to load the same page WITHOUT internet connection it was fast, really fast.
I've remembered that my HTML template had this in the start <base href="http://somesite.com" /> that I've used to load some images whit relative paths in some contents.
Removing that work as charm. So that can be making your web view load slower even if you don't have any reference to extern content in your HTML.
Even in my case, while loading local html files to webview was taking too much time.
Try to load local html files as below, it worked for me:
NSString *htmlFile = [[NSBundle mainBundle] pathForResource:#"website_and_mobile_tnc-1" ofType:#"html"];
NSString* htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:nil];
[_TandCView loadHTMLString:[headerString stringByAppendingString:htmlString] baseURL:nil];
If you want to load using NSData, try to make baseUrl to "nil" in your code.
I have modified your code as below,
NSData *htmlData = [NSData dataWithContentsOfFile:htmlFilePath];
[wView loadData:htmlData MIMEType:#"text/html" textEncodingName:#"UTF-8" baseURL:nil];
I didn't tried this, but please try and let me know.

Is that possible to cache UIWebView in iPhone?

I was using NYTimes iPhone application, I become bit curious when I notice that it cache UIwebview even though I didn't open that article.Does anyone have idea how to do that?
How NYTimes iPhone application doing offline reading?
Any help greatly appreciated.
Thanks,
Amit
I wrote the NYTimes app. Here are some details that you could have gotten by looking inside the app bundle.
I download the HTML for the articles, strip out whatever unsupported HTML and JS crud the producers stuffed in it and cache it in the backing store.
The article content is contained in a series of P tags (HTML fragment). I stuff that into a special HTML skeleton page that ships with the app. The static wrapper page also contains CSS and JS used to properly display the article and lazily load the images.
The image loading is really cool. The web view is notified when the images are ready. layout is not affected because I already know the sizes of the missing images.
You can use UIWebView to load html files stored locally on the iPhone.
NYTimes app is probably caching html and images in local storage.
Search google for "UIWebView local" and you get several useful hits.
I tried it out and it works great:
First, create a "view based application" and add a UIWebView to the NIB.
Second, add this code to your UIViewController code:
- (void)viewDidLoad
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"];
NSURL *url = [NSURL fileURLWithPath:path isDirectory:NO];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
[super viewDidLoad];
}
Third, add a file called "index.html" to your "Resources" folder in xcode and it will be displayed.
UPDATE:
Indeed, the complicated part of this is downloading the images and stylesheets for the webpage. Doing this server side is easy with Simple HTML Parser (and PHP). Just package everything in a zip and download to your iPhone.
Alternatively, you could do it locally with a C/C++/OBJC HTML parser (libxml2.2 is available on iOS). See this SO question Parsing HTML on the iPhone.
It's going to a bit of a project, so good luck.