UIWebView serialization after content has been rendered - ios

I have a very large HTML Document that I need to show in my app. It utilizes CSS Columns, and scrolls horizontally. What I try to do is archive the UIWebView that renders the document in its current state, so that I can unarchive it from CoreData and don't have to let the user wait for a few seconds until it's rendered. So inside my UIWebViewDelegate, I serialize using the following method when webViewDidFinishLoad is called (the content is loaded from string, not from external sources):
[NSKeyedArchiver archivedDataWithRootObject:self.webView];
I checked if webViewDidFinishLoad is called multiple times, but it isn't. This and the core data saving actually works, i.e. it does save and load properly the next time the app is launched. However, while it saves the UIWebView itself, it seems like the content isn't loaded into it, which makes the whole procedure kinda useless for my purpose. Is my understanding of saving an object this way wrong, or is it simply a question of implementation?
Many thanks!

I dont think you should be archiving the UIWebview. Instead you can save the html document fil with custom CSS elements in the documents directory of the app and render it using the filepath using the following code.
self.webview.scalesPageToFit= YES;
[self.webview loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:filePath]]];

Related

ios webview loadHTML string with link css

I load html string in which i link a local css file that lies in docment folder,
...<head><link href="a.css">...</head>...
Then i call webview.loadHTML:htmlstring baseURL:docURL;
the css was loaded OK. Then I change the a.css 's body {background:url(b.gif);} //previous is a.gif, then I pop the webview's view controller, and re-push a new one in which the webview load the same html string that link same css but the body's background image has been changed. Now comes the problem: Some times the webview load the changed background, while some times it will load old image though the css changed! And maybe I realloc the view controller some times, it maybe load the right one!
Can anyone teach me how to fix it?
Thanks a lot!

webViewDidFinishLoad did finish loading but didn't finish showing content on screen

I'm using webViewDidFinishLoad a lot in my app and there's something about UIWebView that really bugs me, well, actually two things.
The first, when I load new content to a UIWebView I will see for half a second the last page that was loaded to the same UIWebView what will force me to "clean" the UIWebView using something like:
[_mainWebView stringByEvaluatingJavaScriptFromString:#"document.open();document.close();"];
before loading the new content.
The second issue I have and that's the main issue for this question is that if i'll load some new content to my UIWebView and do something like this:
[_mainWebView loadHTMLString:htmlString baseURL:nil];
...
- (void)webViewDidFinishLoad:(UIWebView *)webView {
_mainWebView.alpha = 1;
}
In some cases the UIWebView will show up white for half a second before showing up the content. I'm guessing that the content is already loaded into the UIWebView and that's why webViewDidFinishLoad:webView is firing but for small html pages showing to content takes loner than the actual load. Is there any workaround I can use to avoid the blank screen that is showing for a sec or so but still save that second?
I thought about animating the alpha from 0 to 1 but that solution feels kinda lame to me.
Try adding a javascript callback so you know when the web view contents have actually loaded: Javascript in UIWebView callback to C/Objective-C

MonoTouch - Refresh TableView

I am writing a news application for iOS using MonoTouch. The data comes via an OData web sevice.
I have a singleton class called NewsFactory which is responsible for querying the OData feed. Now in the ViewDidLoad method I am retrieving the list of news articles and binding it to the table view.
However - I am not sure how to refresh this every time the app is launched. I don't care much for "pull to refresh". All I want to make sure is that every time the app is launched (from scratch or activated again) that the call to the web service is made to make sure I show the latest info.
In addition, I want to cover for the scenario where the network connectivity is lost when the app is launched and I notify the user. The use closes the app (suspend) and let's say the network connectivity returns - If the user opens the app again, I would like to make sure that I show the latest news articles.
I am building the view hierarchy programmatically. I have navigation controllers and a tab bar controller with 5 tabs.I am targeting iOS 5.
I tried playing with OnActivated and ViewWillAppear and they don't do exactly what I need to do. This is a very common need for any iOS app so there must be a solution - I am new to this so any help is appreciated.
Well you have to think, in general, if you call a method that loads from one source (let's say a text file that has data in it), then you change up the source (change text data), but call the same method when the class is loaded, then the new data will appear when the new class is loaded.
Like for example:
- (void) loadView {
NSString *testString = [NSString stringWithContentsOfFile:filePath];
textView.text = testString;
}
This example shows the setting of text in a file to a UITextView instance. If you load it the first time and the file contained the contents of "Hi", then the textView will say hi. If you change it, then call the same method, then it will show your changed text the second time you load the app.
The point is that if you change data, then call the same method, then you'll see a difference. Unless you're working with a database.
I'd give you a better example if you provide sample code.
EDIT: Not sure if your custom class comes with this function, but it is included in the regular UITableView class:
[tableView reloadData];
You can call that after your array changes internally.

How to calculate scrollWidth of HTML page for fixed height without using UIWebView

We can use the following to calculate the scrollWidth of an HTML page in a UIWebView with a fixed height.
[webView stringByEvaluatingJavaScriptFromString:#"document.documentElement.scrollWidth"]
Is it possible to do this evaluation on local HTML pages without loading a request into a UIWebView?
Would like this to occur on a separate thread.
No(sort of). The html would need to be rendered in some capacity to be able to get any kind of measurements. The reason for this is inherent in the way html/css/javascript work together (javascript modifies html/css properties, css modifies html). If you had to get the width without using a UIWebView, you would be stuck with one of two options:
Render the page yourself, whether it's with your custom code (thousands of man hours, don't do this) or some open source library. I doubt this will be any faster than UIWebView, and will likely introduce unexpected bugs.
Measure the page in the background, and store that value somewhere. This would basically be a form of caching for the size. If the pages are static from when you ship, just do it manually, and hard code it. If they are dynamic, write a class to measure them on startup and store the value. The dynamic measurement would require UIWebView
EDIT:
Are you trying to do this because UIWebView is blocking you're main thread, causing jerkiness in your app? If so, have you considered trying something like this?:
UIWebView *webview = [[UIWebView alloc] initWithFrame:CGRectMake(0,0,320,460)];
webview.delegate = self;
[webview loadRequest: [NSURLRequest requestWithURL:[NSURL urlFromString:#"/path/to/file.html"]]];
... and then later on...
- (void) webViewDidFinishLoad:(UIWebView *)webView
{
// run your code to get scroll width of page
}

synchronous UIWebview request

I'm currently working on a epub application.
So i use UIWebView in order to render my epub (html).
But, for animations reason, i would like to load my request synchronously.
How can i do it ?
I tried to use sendSynchronousRequest, but without success (my request were still asynchronous).
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html
If your problem lays with the delay that UIWebView introduces when rendering the HTML, so that you do not want to show the user a blank page and only after a second or so the rendered page, the only way I have come up to deal with this is:
having initially the UIWebView hidden;
defining webViewDidFinishLoad so that when it fires the web view is made visible.
If you put your UIWebView into a contaning view and define its alpha properly, you can get nice transitions with this approach.
The only real difference in terms of user experience between synchronous and asynchronous is that in the former case the user interface freezes up. So if that is the effect you want, just set all the userInteractionEnabled properties to NO when you launch the request, and switch them back on once the request is finished in connectionDidFinishLoading:.
I think you can get the html as a string with this:
NSError * error;
NSURL * url = [NSURL URLWithString:#"http://www.yoururl.com"];
NSString * htmlContent = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
And the load the html:
[webView loadHTMLString:htmlContent baseURL:url];

Resources